我在使用 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();
}
我在
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();
}
这是一个简单的解决方案我从@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:热爱你所做的事情💚。