我需要设置一个GLSL片段着色器来更改当前正在处理的片段之外的片段的颜色。由于这似乎不太可取,我将提供一个非常简短的背景。
该项目利用渲染过程,将给定模型绘制到具有与纹理贴图中的UV坐标对应的唯一颜色的FBO中。然后对这些颜色进行采样并转换为图像坐标,以便可以根据相机可见的内容更新模型的纹理贴图。基本上:
Render model to FBO
For each FBO pixel
1. sample secondary texture based on FBO pixel position
2. convert color at current pixel to image coordinate for the model's texture map
3. update model's texture with sampled secondary texture at calculated coordinate
End loop
问题是当前的实现非常受CPU限制,因此我正在读取FBO中的像素,然后对它们进行操作。理想情况下,因为我已经在片段着色器中使用了片段的颜色,所以我想简单介绍该过程的最后几个步骤,并将所有内容保存在GPU上。
我遇到的具体问题是我不知道如何(或者甚至可能)让片段着色器设置它未处理的片段的颜色。如果我不能通过使用一个特大的FBO来工作,只是偏移我想要设置颜色的片段,我可以做一些直接写入纹理的东西吗?
非常感谢任何帮助/建议。谢谢!
答案 0 :(得分:5)
片段着色器无法写入正在处理的片段以外的任何位置。您可能想要做的是乒乓渲染。
在你的代码中,你有三个纹理,与你列出的任务相匹配:
在第一次运行时,您将使用(1)和(2)作为源纹理,以绘制到(3)。下一次循环你将使用(1)和(3)写入(2)。然后你切换回使用(1)和(2)写入(3)。等等。
所以(2)和(3)与framebuffer对象连接,纹理作为颜色缓冲区提供,代替渲染缓冲区。
NVidia在2009年创作了GL_NV_texture_barrier extension,允许您将(2)和(3)压缩成单个纹理,只要您明确指出您正在阅读的地方和您写作的地方之间的分界线。我没有专业知识可以说它有多广泛。
尝试读取和写入相同的纹理(与FBO一样)否则会在OpenGL中产生未定义的结果。提示硬件级别的问题与缓存和多重采样有关。
答案 1 :(得分:2)
据我所知,您需要在OpenGL中执行散射操作(均匀FBO像素空间 - >随机网格UV纹理目标)。有一种方法可以做到这一点,并不像你想象的那么简单,甚至没有那么快,但我找不到更好的方法:
GL_POINTS
的绘图调用,其大小等于源FBO的宽度*高度。gl_VertexID
计算原始屏幕坐标。gl_Position
并将目标颜色传递给片段着色器。这将使GPU遍历每个原始FBO像素,并将计算出的颜色分散到目标纹理上。