【问题标题】:glsl pixel shader- distance to closest target pixelglsl像素着色器-到最近目标像素的距离
【发布时间】:2013-12-18 06:37:48
【问题描述】:

我有一个随机放置“目标”像素的 2k x 1k 图像。这些像素是纯红色的。

在片段/像素着色器中,对于每个不是红色(目标颜色)的像素,我需要找到到 最近红色像素的距离。我将使用这个距离值来创建渐变。

我找到了这个答案,这似乎最接近我的问题 --- Finding closest non-black pixel in an image fast --- 但它不是 glsl 特定的。

我可以选择将我的红色目标像素作为纹理缓冲区数组发送到碎片着色器中。但我认为如果我不需要它会更干净。

【问题讨论】:

    标签: opengl glsl shader


    【解决方案1】:

    着色器无法读取和写入相同的纹理,因为这会引入过多的约束和执行顺序的复杂性,并使缓存变得更加困难。所以你说的是发送一些关于红色像素的数据并获取距离信息。

    片段着色器并行运行,执行随机访问纹理读取比从着色器外部已知位置读取要昂贵得多,这主要是出于流水线的考虑。在顶点处已知采样坐标然后在几何体的面上进行插值的预编程情况仍然是访问纹理的最佳方式。

    因此,为每个像素编写一个向外搜索红色像素的着色器将是非常低效的。这绝对是可能的,做很多你链接到的算法,但可能不是最聪明的方法。

    理想情况下,您应该换一种说法,并使用某种积累。所以:

    1. 将输出缓冲区清除为最大值;
    2. 对于每个红色位置:
      1. 对于每个输出片段,计算与该位置的距离;
      2. 检查已为该片段存储的距离;
      3. 如果新距离小于存储的距离,则替换存储的版本。

    在 OpenGL 中执行此操作的最简单方法可能是使用深度缓冲区,因为它的每个片段步骤 (2) 和 (3) 直接在硬件中实现。

    因此,对于每个片段,您将计算与当前红色片段的距离。你将把它作为深度输出。完成所有红点后,您可以将深度缓冲区用作输出适当颜色的着色器的输入。

    为了避免 2000 个红点变成 2000-pass 绘制算法,这种算法会很快耗尽内存带宽,您可能需要编写一个着色器,一次处理大量红点并输出单个深度价值。

    您应该查看GL_MAX_UNIFORM_LOCATIONS 以了解您一次可以推送多少个制服。在最新版本的桌面 OpenGL 上保证至少为 1024。您可能希望动态生成着色器。

    【讨论】:

      【解决方案2】:

      为什么不用大半径对整个图像进行高斯模糊处理,但在每次迭代时,不断将红色像素以全强度添加回方程中,这样它们就会消失。最终模糊的红色通道将是您的距离值 - 较高的值更接近红色像素。这是一个近似值,但您可以使用高度优化的模糊着色器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-25
        • 1970-01-01
        相关资源
        最近更新 更多