libGDX 帧缓冲区 Alpha 问题

问题描述 投票:0回答:2

我在使用 libGDX FrameBuffer 和 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();
}

Expected Result 预期结果

Actual Result 实际结果

libgdx alpha framebuffer
2个回答
1
投票

我在

FrameBuffer
中遇到了与半透明颜色几乎相同的问题,您可以在我的badlogic论坛主题此处找到问题和解决方案。

基本上,您需要在预乘 alpha 状态下绘制到

FrameBuffer
。您可以通过创建自定义片段着色器来完成此操作(我的完整代码在该主题上)。然后将混合模式设置为匹配(GL_ONE、GL_ONE_MINUS_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();
}

0
投票

这是一个简单的解决方案我从@hamham之前的答案中得出:


private val colorWhite = Color.WHITE

fbo!!.begin()
     ScreenUtils.clear(Color.CLEAR)

     fboBatch.begin()
     fboBatch.projectionMatrix = camera.combined


     fboBatch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA); //pre-multiplied alpha ShaderProgram
     super.draw(fboBatch, parentAlpha)
     fboBatch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); //default blend mode


     fboBatch.color = colorWhite

     fboBatch.end()
fboGroup!!.end(screenXInPixels, screenYInPixels, screenWidthInPixels, screenHeightInPixels)

PS。 Vel_daN:热爱你所做的事情💚。

© www.soinside.com 2019 - 2024. All rights reserved.