Libgdx render() 中的混合对比度问题;
Libgdx blending contrast issue in render();
在 Libgdx 1.x 阶段,我的目标是在我的屏幕上应用深色半透明遮罩,除了应该显示原始屏幕的区域。
我的全局渲染方法:
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setShader(null);
update();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.begin();
darkener.draw(batch, 0.7f);
spotlight.draw(batch, 1f);
batch.end();
}
Darkener 和 Spotlight 对象的两个实例都是由纯白色 4x4 纹理制成的 Sprites:
spotlight = new Sprite(new Texture(Gdx.files.internal("data/ui/whitepixel.png")));
darkener = new Sprite(new Texture(Gdx.files.internal("data/ui/whitepixel.png")));
我将 Darkener 对象设置为屏幕大小,将 Spotlight 对象设置为我不想变暗的区域大小。
这是我的对象暗化器的绘制方法:
public void draw(Batch batch, float alpha) {
darkener.draw(batch, alpha);
}
以及我的 Spotlight 对象的绘制方法:
public void draw(Batch batch, float alpha) {
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
spotlight.draw(batch, alpha);
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
}
我的问题是混合:
使用参数:
darkener.draw(batch, 0.7f);
spotlight.draw(batch, 1f);
保留的(聚光灯)区域比原始区域暗。
带参数:
darkener.draw(batch, 0.3f);
spotlight.draw(batch, 1f);
保留的(聚光灯)区域比原始区域更亮(饱和)。
使用参数:
darkener.draw(batch, 0.5f);
spotlight.draw(batch, 1f);
保留的(聚光灯)区域和原来的一模一样(所以,如我所愿)。问题是我希望能够为我的 Darkener 设置不同的值 < 0.5f 或 > 0.5f。
我做错了什么?
您为聚光灯使用的混合函数采用当前像素亮度并将其乘以 (1+alpha)。
因此,如果您将亮度调暗到 0.7(使用 0.3 的暗化器 alpha),您希望聚光灯将亮度乘以 1/0.7 = 1.429,因此您应该使用 0.429 的聚光灯 alpha。所以:
spotlightAlpha = 1/(1-darkenerAlpha) - 1; //assuming darkener RGB is black
问题是如果你调暗到小于 0.5 的亮度(较暗的 alpha > 0.5),因为 alpha 不能大于 1。你将不得不 运行 重复使用 alpha 1 的聚光灯,直到亮度达到高于 0.5,然后再使用适当的值一次。
颜色越深,颜色精度就越低,因此这种方法可能不适用。可能要考虑改为绘制 8 个暗框。如果你想要聚光灯是非矩形的,你可以让它的精灵倒过来填充中间的矩形。
在 Libgdx 1.x 阶段,我的目标是在我的屏幕上应用深色半透明遮罩,除了应该显示原始屏幕的区域。
我的全局渲染方法:
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setShader(null);
update();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.begin();
darkener.draw(batch, 0.7f);
spotlight.draw(batch, 1f);
batch.end();
}
Darkener 和 Spotlight 对象的两个实例都是由纯白色 4x4 纹理制成的 Sprites:
spotlight = new Sprite(new Texture(Gdx.files.internal("data/ui/whitepixel.png")));
darkener = new Sprite(new Texture(Gdx.files.internal("data/ui/whitepixel.png")));
我将 Darkener 对象设置为屏幕大小,将 Spotlight 对象设置为我不想变暗的区域大小。
这是我的对象暗化器的绘制方法:
public void draw(Batch batch, float alpha) {
darkener.draw(batch, alpha);
}
以及我的 Spotlight 对象的绘制方法:
public void draw(Batch batch, float alpha) {
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
spotlight.draw(batch, alpha);
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
}
我的问题是混合: 使用参数:
darkener.draw(batch, 0.7f);
spotlight.draw(batch, 1f);
保留的(聚光灯)区域比原始区域暗。
带参数:
darkener.draw(batch, 0.3f);
spotlight.draw(batch, 1f);
保留的(聚光灯)区域比原始区域更亮(饱和)。
使用参数:
darkener.draw(batch, 0.5f);
spotlight.draw(batch, 1f);
保留的(聚光灯)区域和原来的一模一样(所以,如我所愿)。问题是我希望能够为我的 Darkener 设置不同的值 < 0.5f 或 > 0.5f。
我做错了什么?
您为聚光灯使用的混合函数采用当前像素亮度并将其乘以 (1+alpha)。
因此,如果您将亮度调暗到 0.7(使用 0.3 的暗化器 alpha),您希望聚光灯将亮度乘以 1/0.7 = 1.429,因此您应该使用 0.429 的聚光灯 alpha。所以:
spotlightAlpha = 1/(1-darkenerAlpha) - 1; //assuming darkener RGB is black
问题是如果你调暗到小于 0.5 的亮度(较暗的 alpha > 0.5),因为 alpha 不能大于 1。你将不得不 运行 重复使用 alpha 1 的聚光灯,直到亮度达到高于 0.5,然后再使用适当的值一次。
颜色越深,颜色精度就越低,因此这种方法可能不适用。可能要考虑改为绘制 8 个暗框。如果你想要聚光灯是非矩形的,你可以让它的精灵倒过来填充中间的矩形。