GLSL:访问帧缓冲区以获取RGB并更改它

时间:2017-02-03 04:06:51

标签: opengl glsl shader

我想访问framebuffer来获取RGB并更改每个像素的值。这是因为glReadPixels和glDrawPixels使用起来太慢,所以我应该使用着色器而不是使用它们。

现在,我编写代码,并成功使用GLSL着色器显示三维模型。

我按如下方式画了两个立方体。

.... 
glDrawArrays(GL_TRIANGLES, 0, 12*6);
.... 

和片段着色器:

varying vec3 fragmentColor;
void main()
{
    gl_FragColor = vec4(fragmentColor, 1);
}

然后,我如何访问RGB值并进行更改? 例如,如果窗口上的(u1,v1)和(u2,v2)的像素值是(0,0,255),那么我想将它们更改为(255,0,0)

1 个答案:

答案 0 :(得分:1)

除了OpenGL ES-only扩展外,片段着色器不能只读取当前的帧缓冲区。否则,我们不需要blending

您也不能只渲染到您在着色器中读取的图像。因此,如果您需要进行某种后处理,那么最好通过渲染到单独的图像来完成。也就是说,您对图像1进行渲染,然后将其作为纹理绑定并更改FBO,以便渲染到图像2。

或者,如果您有权访问OpenGL 4.5/ARB/NV_texture_barrier,则可以使用纹理障碍来处理此问题。如果将当前帧缓冲区的图像绑定为纹理,则允许您进行单个读取/修改/写入传递。您在执行读取/修改/写入之前发出屏障,然后将该纹理绑定到采样器,同时仍然呈现给该帧缓冲区。

此外,这要求FS从精确纹理中读取它要写入的内容。假设视口锚定在0,0,则代码为texelFetch(sampler, ivec2(gl_FragCoord.xy), 0)。你不能从别人的纹理元素中读取并修改它。

显然你必须渲染到纹理;你不能使用默认的帧缓冲。

纹理屏障可用于从不同的纹素读取的情况。但这需要做类似第一种切换绑定图像的情况。虽然你不需要完全改变FBO;您可以更改渲染到的FBO的区域。也就是说,只要您从不同的区域读取而不是渲染,并且在这些区域之间切换时适当地使用障碍,一切都很好。