【发布时间】:2014-06-29 22:40:09
【问题描述】:
我正在尝试混合从 FBO 获得的两种不同的纹理(场景和云)并将它们绘制在四边形上。
uniform sampler2D u_texture;
uniform sampler2D u_texture2;
uniform vec2 u_res;
void main(void)
{
vec2 texCoord = gl_FragCoord.xy / u_res.xy;
vec4 sceneColor = texture2D(u_texture, texCoord);
vec4 addColor = texture2D(u_texture2, texCoord);
gl_FragColor = sceneColor+addColor;
}
glBlendFunc 是
Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
我尝试了glBlendFunc 的所有组合,上面的组合是最好的组合。
创建 FBO:
fbClouds = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
fbScene = new FrameBuffer(Format.RGB565, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
fbMix = new FrameBuffer(Format.RGB565, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
创造云:
fbClouds.begin();
Gdx.gl.glClearColor(0, 0, 0, 0); // to make it transparent
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
for (Integer e : drawOrder) {
if(isVisible(cam, clouds[e])){
drawLightning(e, modelBatch);
modelBatch.render(clouds[e], cloudShader);
modelBatch.flush();
}
}
modelBatch.end();
fbClouds.end();
渲染代码:
Gdx.gl20.glDisable(GL20.GL_BLEND);
//Gdx.gl20.glEnable(GL20.GL_BLEND);
//Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
fbMix.begin();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
mixShader.begin();
fbScene.getColorBufferTexture().bind(1);
mixShader.setUniformi("u_texture", 1);
fbClouds.getColorBufferTexture().bind(0);
mixShader.setUniformi("u_texture2", 0);
mixShader.setUniformf("u_res", Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
quad.render(mixShader, GL20.GL_TRIANGLES);
mixShader.end();
fbMix.end();
所以,我得到了意想不到的结果(云完全是白色的,虽然它们应该是灰色的):
如果我使用modelbatch 渲染云,结果应该是:
混合两种纹理而不失色的正确方法是什么?
【问题讨论】:
-
它变成了亮白色,因为你在亮蓝色中添加了灰色。但我不确定你的描述到底发生了什么。绘制到其中一个 FBO 时使用的混合函数是什么,还是用于将所有 FBO 绘制到屏幕上?在您使用的片段着色器中,您需要使用云纹理的 alpha 乘以云纹理,并使用(1- 云纹理的 alpha)乘以天空纹理。但是您需要确保您的云的 FBO 支持 alpha 并写入该 alpha 通道。有点绕。也许有更简单的方法?
-
@Tenfour04,我应该使用哪个公式?你能根据我的着色器源代码给我看吗?云可以是红色或绿色,没关系。在任何情况下它们都会变白!
-
我仍然不清楚你到底在做什么。如果你能澄清一下,我想我有一个可行的解决方案。您在顶部显示一个片段着色器。我想你的意思是你把天空和太阳画到一个 FBO,把云画到另一个 FBO。假设这是对的,你是如何使用 ModelInstance 绘制云的?你画云的 FBO 的清晰颜色是什么?您提到的混合函数是用于将云绘制到其 FBO 中,还是您用于将具有两个 FBO 的 Quad 绘制到主缓冲区?
-
您这样做是为了节省填充率,因为云层重叠很多,对吧?有什么理由不能将天空和太阳直接绘制到主缓冲区并且只为云使用一个 FBO?
-
@Tenfour04,是的,我使用
ModelBatch将云绘制到一个 FBO,该 FBO 被降采样两次,而场景的其他元素则绘制到另一个 FBO。我必须这样做以增加 fps(如您在上面的屏幕截图中所见)。我将Format.RGB565用于云的FBO,清晰的颜色是黑色。我使用blend func将带有两个FBO 的Quad 绘制到主缓冲区。我不知道如何将主缓冲区(太阳和天空)与云 FBO 混合(以防我直接在主缓冲区中绘制它们(太阳和天空))。因此,我使用上面的着色器和blend func在 Quad 上绘制它们。我希望它足够清楚。
标签: libgdx glsl opengl-es-2.0 fragment-shader