着色器无法读取和写入相同的纹理,因为这会引入过多的约束和执行顺序的复杂性,并使缓存变得更加困难。所以你说的是发送一些关于红色像素的数据并获取距离信息。
片段着色器并行运行,执行随机访问纹理读取比从着色器外部已知位置读取要昂贵得多,这主要是出于流水线的考虑。在顶点处已知采样坐标然后在几何体的面上进行插值的预编程情况仍然是访问纹理的最佳方式。
因此,为每个像素编写一个向外搜索红色像素的着色器将是非常低效的。这绝对是可能的,做很多你链接到的算法,但可能不是最聪明的方法。
理想情况下,您应该换一种说法,并使用某种积累。所以:
- 将输出缓冲区清除为最大值;
- 对于每个红色位置:
- 对于每个输出片段,计算与该位置的距离;
- 检查已为该片段存储的距离;
- 如果新距离小于存储的距离,则替换存储的版本。
在 OpenGL 中执行此操作的最简单方法可能是使用深度缓冲区,因为它的每个片段步骤 (2) 和 (3) 直接在硬件中实现。
因此,对于每个片段,您将计算与当前红色片段的距离。你将把它作为深度输出。完成所有红点后,您可以将深度缓冲区用作输出适当颜色的着色器的输入。
为了避免 2000 个红点变成 2000-pass 绘制算法,这种算法会很快耗尽内存带宽,您可能需要编写一个着色器,一次处理大量红点并输出单个深度价值。
您应该查看GL_MAX_UNIFORM_LOCATIONS 以了解您一次可以推送多少个制服。在最新版本的桌面 OpenGL 上保证至少为 1024。您可能希望动态生成着色器。