Opengl - 附加到纹理

Opengl - appending to a texture

我想创建一个纹理系统,我 添加 到纹理, 覆盖它。我的纹理具有整数值(32 位)。我想要什么:例如。我有一个位为 100 的整数像素,我想给它加 10,所以它变成 110。

我当前的实现有两个纹理,一个是前一个纹理,另一个是要在上面书写的纹理。先前纹理的值被读取,然后用新数据重写。有没有更好的方法来这样做,因为使用两个纹理感觉效率很低?

根据 "appending" 的含义,您可以使用 加法混合 :

glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);

然后,片段着色器的输出将添加到颜色缓冲区的当前内容中。如果使用 FBO 渲染到纹理中,则可以直接添加到此纹理中。

你应该小心不要创建任何反馈循环,所以你的片段着色器的结果不应该依赖于你渲染到的相同纹理的任何样本。

更新

如评论中所述,有问题的纹理具有 GL_RED_INTEGER 格式。不幸的是,混合仅适用于浮点颜色缓冲区(包括规范化整数),而不适用于非规范化整数。

但是,还有另一种可能的方法。最近的 OpenGL 放宽了我之前提到的 "feedback loops" 的规则。扩展 GL_ARB_texture_barrier 明确允许片段着色器从它正在写入的同一纹理读取像素:

Specifically, the values of rendered fragments are undefined if any shader stage fetches texels and the same texels are written via fragment shader outputs, even if the reads and writes are not in the same Draw call, unless any of the following exceptions apply:

  • The reads and writes are from/to disjoint sets of texels (after accounting for texture filtering rules).

  • There is only a single read and write of each texel, and the read is in the fragment shader invocation that writes the same texel (e.g. using "texelFetch2D(sampler, ivec2(gl_FragCoord.xy), 0);").

  • [...]

此扩展已提升为 OpenGL 4.5 的核心功能。这是相当新的,在很多平台上都没有,所以不清楚你是否可以使用它...