【发布时间】:2021-08-13 19:02:16
【问题描述】:
当使用glReadPixels 读取 rgba(1,1,1,0.1) 时,将导致 rgba(0.1,0.1,0.1,???)。该函数正在从帧缓冲区读取修改后的值,我假设是因为 alpha 混合。
我使用的示例具有以下设置:
片段着色器:
String fragmentShaderSource =
" #version 440\n" +
" out vec4 gl_FragColor;\n" +
" in vec4 gl_FragCoord; \n" +
" varying vec2 v_texCoords;\n" +
"\n" +
" uniform float chunkSize;\n" +
" layout(binding=1)uniform sampler2D inputs1;\n" +
" layout(binding=2)uniform sampler2D inputs2;\n" +
"\n" +
" void main(void){\n" +
" gl_FragColor.r = 1;\n" +
" gl_FragColor.g = 1;\n" +
" gl_FragColor.b = 1;\n" +
" gl_FragColor.a = 0.1;\n" +
" }"
;
初始化:
fboHandle = Gdx.gl.glGenFramebuffer();
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, fboHandle);
/* Create output texture */
outputTextureHandle = Gdx.gl.glGenTexture();
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, outputTextureHandle);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);
Gdx.gl.glTexImage2D(
GL20.GL_TEXTURE_2D, 0, GL30.GL_RGBA32F,
width, height, 0, GL20.GL_RGBA, GL20.GL_FLOAT, null
);
/* Configure Framebuffer */
/* Set "renderedTexture" as our colour attachement #0 */
Gdx.gl.glFramebufferTexture2D(
GL20.GL_FRAMEBUFFER, GL20.GL_COLOR_ATTACHMENT0,
GL20.GL_TEXTURE_2D, outputTextureHandle, 0
);
渲染后:
Gdx.gl30.glReadPixels(0,0,width, height, GL20.GL_RGBA, GL20.GL_FLOAT, resultBuf);
System.out.println("result r: " + resultBuf.get(0));
System.out.println("result g: " + resultBuf.get(1));
System.out.println("result b: " + resultBuf.get(2));
System.out.println("result a: " + resultBuf.get(3));
输出:
result r: 0.1
result g: 0.1
result b: 0.1
result a: 0.90999997
我不明白为什么 alpha 值是这样的。根据this answer 的说法,在渲染到帧缓冲区时,alpha 通道会丢失,并用于修改像素值。
我的问题:
- 当 rgb 值发生“组合”时,Alpha 通道会发生什么情况?
- 我了解除了 alpha 以外的像素值会发生什么情况,但这是为什么呢?
- 是否可以禁用此行为,以便使用
glReadPixels保留 alpha 值和原始像素值?
补充:当Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ZERO); 被调用,或使用Gdx.gl.glDisable(GL20.GL_BLEND); 禁用混合时,观察到相同的行为。
使用渲染缓冲区代替纹理颜色附件具有相同的效果。
【问题讨论】:
-
您是否碰巧调用
glReadBuffer将glReadPixels指向您的帧缓冲区对象?我认为默认情况下,像素将从后台缓冲区中读取;要读取 FBO 中的值,您需要在读取像素之前调用glReadBuffer(GL_COLOR_ATTACHMENT0);。在您的示例中,您正确请求了一个具有 alpha 值存储的渲染表面,但取决于您如何配置应用程序的默认帧缓冲区(即,通过 EGL、GLX 等与窗口关联的帧缓冲区),它可能不包括任何用于存储 alpha 值的位。 -
我没有明确地调用它,但现在我调用了它,它仍然产生相同的结果。谢谢你的建议!
标签: java opengl-es libgdx lwjgl framebuffer