我有一个2k x 1k的图像,随机放置“目标”像素。这些像素是纯红色的。
在frag / pixel着色器中,对于非红色(目标颜色)的每个像素,我需要找到距最近的红色像素的距离。我将使用此距离值来创建渐变。
我找到了这个答案,这似乎与我的问题最接近--- Finding closest non-black pixel in an image fast --- 但这不是特定的glsl。
我可以选择将红色目标像素作为纹理缓冲区数组发送到frag着色器中。但我认为如果我不需要它会更清洁。
答案 0 :(得分:3)
着色器无法读取和写入相同的纹理,因为这会对执行序列引入太多约束和复杂性,并且会使缓存变得更加困难。所以你在谈论发送一些关于红色像素的数据并获取距离信息。
碎片着色器并行运行,执行随机访问纹理读取比从着色器外部已知位置读取要昂贵得多,这主要是由于流水线操作的考虑因素。预先编程的情况,其中采样坐标在顶点处已知,然后在几何体的面上进行插值,这仍然是访问纹理的最佳方式。
因此,编写一个着色器,对于每个像素,向外搜索红色像素将是非常低效的。这绝对是可能的,做了很多链接的算法,但可能不是最聪明的方法。
理想情况下,你会用相反的方式表达事物并使用某种积累。所以:
在OpenGL中执行此操作的最简单方法可能是使用深度缓冲区,因为它具有直接在硬件中实现的每片段步骤(2)和(3)。
因此,对于每个片段,您将计算与当前红色片段的距离。你将把它作为深度输出。当您完成所有红点后,您可以使用深度缓冲区作为输出适当颜色的着色器的输入。
为了避免2000个红点变成一个2000遍的绘图算法,这个算法很快就会对内存带宽产生影响,你可能想要编写一个单一的着色器,它可以同时处理大量的红点并输出一个深度值。
您应该检查GL_MAX_UNIFORM_LOCATIONS
以了解您可以一次推出多少件制服。在最新版本的桌面OpenGL上保证至少为1024。您可能希望动态生成着色器。
答案 1 :(得分:0)
为什么不高斯模糊大半径的整个图像,但是在每次迭代时都要将红色像素以完全强度添加回方程中,以便它们流出。最终模糊的红色通道将是您的距离值 - 较高的值更接近红色像素。这是近似值,但您可以使用经过大量优化的模糊着色器。