3

有没有办法,而不是使用 gl_FragColor 输出的预定坐标,而是通过其坐标设置特定像素的颜色?

我目前正在尝试通过着色器实现 Mean Shift 算法。我的输入是黑白纹理,其中白点代表要聚类的点,黑色代表无数据。

在计算邻域中所有点位置的加权平均值后,我必须将结果位置中的像素设置为代表集群的新颜色。

例如,如果我查看以与 fragcoord 相关的像素为中心的 18x18 邻域并找到 3 个白色像素: Fragcoord = 30,33 像素 1:坐标 (30,33) 像素 2:坐标 (27,33) 像素 3:坐标 (30,30)

在计算他们的位置的平均值后,我将得到 (29,32)。有没有办法在具有不同 fragcoord(例如 30,33)的着色器单元中将 29,32 的像素设置为不同的颜色?

像 gl_FragColor(vec2(29,32)) = vec4(1.0,1.0,1.0,1.0); ?

4

2 回答 2

3

不,那是不可能的。为特定位置的特定片段调用片段着色器,并且只能输出该特定片段(或丢弃整个片段)的值,然后在该预定片段位置处写入帧缓冲区。

您可以做的根本不是将输出写入帧缓冲区,而是写入其他存储,任意图像(使用图像加载/存储)或着色器存储缓冲区。但这两个功能需要相当现代的硬件功能(GL 4+ 硬件)。在这种情况下,您还可以首先使用适当的计算着色器(或者像CUDAOpenCL这样的实际计算框架,如果您不需要任何其他 OpenGL 功能)来完成整个工作。


另一种也适用于旧硬件的方法是在顶点着色器而不是片段着色器中做你的事情。这样您就可以相应地计算顶点的剪辑空间位置(然后变成片段位置)。当使用几何着色器而不是顶点着色器时,您甚至可以分散数据(为单个输入计算多个输出)或丢弃东西。

于 2013-07-30T10:55:33.347 回答
3

正如克里斯蒂安所说,这是不可能的。如果您可以使用它,计算框架或图像加载/存储是您切换到的最佳选择。

如果您必须在没有图像加载/存储的情况下使用 GLSL,您可以选择:如果您的图像总共有 n 个像素,则将 n 个顶点作为点发送到顶点着色器;在顶点着色器中,根据您的 gl_VertexID(在 GLSL 1.10 中可用......如果您有 1.40+,您可能应该使用实例化和 gl_InstanceID )从纹理中读取,并定位该点,以便当它进入片段着色器时,它完全覆盖了您想要的像素。然后无论如何都让像素着色器输出白色。

它是一种 hack,但如果您没有其他选择,它可能会正常工作。

于 2013-07-30T12:28:08.557 回答