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 个暗框。如果你想要聚光灯是非矩形的,你可以让它的精灵倒过来填充中间的矩形。