libGDX帧缓冲区Alpha问题

libGDX帧缓冲区Alpha问题,libgdx,alpha,framebuffer,Libgdx,Alpha,Framebuffer,我对libGDX帧缓冲区和Alpha有问题。下面是预期结果和实际结果的两幅图像。有人能告诉我我做错了什么,我怎样才能改正它吗。代码如下: FrameBuffer buffer; Sprite sprite; SpriteBatch batch; Texture texture1; Texture texture2; Texture texture3; Sprite texture2Sprite; @Override public void create () { batch = ne

我对libGDX帧缓冲区和Alpha有问题。下面是预期结果和实际结果的两幅图像。有人能告诉我我做错了什么,我怎样才能改正它吗。代码如下:

FrameBuffer buffer;
Sprite sprite;

SpriteBatch batch;
Texture texture1;
Texture texture2;
Texture texture3;
Sprite texture2Sprite;

@Override
public void create () {
    batch = new SpriteBatch();

    texture1 = new Texture("1.png");
    texture2 = new Texture("2.png");
    texture3 = new Texture("3.png");

    texture2Sprite = new Sprite(texture2);
    texture2Sprite.setAlpha(0.5f);
    texture2Sprite.setPosition(100, 100);

    buffer = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
    sprite = new Sprite(buffer.getColorBufferTexture());
    sprite.flip(false, true);
}

public void createFBO()
{
    buffer.begin();

    Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.begin();
    batch.draw(texture1, 0f, 0f);

    texture2Sprite.draw(batch);

    batch.end();
    buffer.end();
}

@Override
public void render () {

    createFBO();

    Gdx.gl.glClearColor(0f, 0f, 1f, 1f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.begin();
    batch.enableBlending();
    batch.draw(texture3, 200, 200);
    sprite.draw(batch);

    batch.end();
}
预期结果


实际结果

我在
帧缓冲区
中遇到了几乎相同的半透明颜色问题,您可以在我的badlogic论坛主题中找到问题和解决方案

基本上,您需要以预先乘以的alpha状态绘制到
帧缓冲区。您可以通过创建自定义片段着色器来实现这一点(我的完整代码在主题中)。然后将混合模式设置为匹配(GL_ONE,GL_ONE,减去SRC_ALPHA)

然后使用相同的混合函数但默认着色器绘制精灵。你应该得到这样的结果

public void createFBO(){
    buffer.begin();
    batch.begin();

    Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.setShader(pmaShaderProgram); //pre-multiplied alpha ShaderProgram
    batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
    batch.draw(texture1, 0f, 0f);
    texture2Sprite.draw(batch);
    batch.setShader(null); //default ShaderProgram
    batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); //default blend mode

    batch.end();
    buffer.end();
}

@Override
public void render () {
    createFBO();

    batch.begin();
    batch.enableBlending();

    Gdx.gl.glClearColor(0f, 0f, 1f, 1f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.draw(texture3, 200, 200);

    batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
    sprite.draw(batch);
    batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

    batch.end();
}

嘿,谢谢它工作得很好。。。不过,我还有一次跟进。假设我想画一些东西到帧缓冲区,它有一个alpha组件,但也使用另一个着色器程序。我该怎么办?很高兴这对你有用。我认为解决下一个问题的唯一方法是创建其他自定义着色器的另一个版本,并对其进行修改以绘制预乘alpha。我想大多数着色器都可以简单地在末尾添加必要的线条<代码>gl_FragColor.rgb*=gl_FragColor.a