在glsl片段着色器中如何输出特定的坐标?

3
是否有一种方法,可以通过像素坐标来设置特定像素的颜色,而不是使用由gl_FragColor预设的坐标作为输出?
我目前正在尝试通过着色器实现Mean Shift算法。我的输入是一个黑白纹理,其中白点表示要聚类的点,黑色表示无数据。
在计算邻域内所有点位置的加权平均值之后,我必须将结果位置中的像素设置为表示聚类的新颜色。
例如,如果我查看以与fragcoord相关的像素为中心的18x18邻域,并找到3个白色像素: Fragcoord = 30,33 Pixel 1: coordinate (30,33) Pixel 2: coordinate (27,33) Pixel 3: coordinate (30,30)
在计算它们位置的平均值之后,我将得到(29,32)。是否有一种方法可以在具有不同fragcoord(例如30,33)的着色器单元中设置29,32处的像素颜色?
例如:gl_FragColor(vec2(29,32)) = vec4(1.0,1.0,1.0,1.0);?
2个回答

3
不,这是不可能的。片段着色器被调用以针对特定位置的特定片段,并且只能输出该特定片段的值(或放弃整个片段),然后将这些值写入到完全预先确定的片段位置的帧缓冲区中。
你可以做的是根本不将输出写入帧缓冲区,而是写入其他存储,例如任意图像(使用image load/store)或shader storage buffer。但是这两个功能需要相当现代的硬件能力(GL 4+硬件)。在这种情况下,您也可以首先使用适当的compute shader(或实际的计算框架,如CUDA或OpenCL,如果您不需要任何其他OpenGL功能)。
另一种适用于旧硬件的方法是在顶点着色器中完成操作,而不是片段着色器。这样,您可以相应地计算顶点的剪裁空间位置(然后变成片段位置)。使用几何着色器而不是顶点着色器时,甚至可以散布数据(对单个输入计算多个输出)或丢弃内容。

3
如Christian所说,这是不可能的。如果您能使用图像加载/存储,则最好选择计算框架或图像加载/存储来切换。
如果没有图像加载/存储,但必须使用GLSL,则有一个选择:如果您的图像总共有n个像素,则作为点将n个顶点发送到顶点着色器; 在顶点着色器中,根据gl_VertexID(在GLSL 1.10中可用...如果您使用的是1.40 +,则应该使用实例化和gl_InstanceID)从纹理中读取,并定位点,以便当它进入片段着色器时,它正好覆盖您想要的像素。然后只需使像素着色器输出白色即可。
这是一种hack方法,但如果没有其他选择,它可能会很好地解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接