我想访问帧缓冲区以获取 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)
最佳答案
除了仅限 OpenGL ES 的扩展之外,片段着色器不能只从当前帧缓冲区读取。否则,我们就不需要 blending .
您也不能只渲染到着色器中读取的图像。因此,如果您需要进行某种后处理,那么最好通过渲染到单独的图像来完成。也就是说,您对图像 1 进行渲染,然后将其绑定(bind)为纹理并更改 FBO,以便渲染到图像 2。
或者,如果您有权访问 OpenGL 4.5/ARB/NV_texture_barrier ,那么你可以使用纹理屏障来处理这个问题。如果您将当前帧缓冲区的图像绑定(bind)为纹理,则这允许您单个读取/修改/写入过程。您可以在执行读取/修改/写入之前发出屏障,然后将该纹理绑定(bind)到采样器,同时仍然渲染到该帧缓冲区。
此外,这还要求 FS 从它要写入的精确纹理元素中读取。假设视口(viewport)锚定在 0,0,则代码为 texelFetch(sampler, ivec2(gl_FragCoord.xy), 0)
。您无法读取他人的纹理像素并对其进行修改。
显然你必须渲染到纹理;您不能为此使用默认帧缓冲区。
纹理屏障可用于从不同纹素读取和写入的情况。但这需要执行类似于切换绑定(bind)图像的第一种情况的操作。尽管您不需要完全更改 FBO;您可以更改渲染到的 FBO 区域。也就是说,只要您从与渲染目标不同的区域进行读取,并且在这些区域之间切换时适本地使用屏障,一切都很好。
关于opengl - GLSL : accessing framebuffer to get RGB and change it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42016590/