在Fragmentshader中访问不同的片段OpenGL

时间:2015-12-04 19:03:47

标签: opengl parallel-processing glsl fragment-shader

我可以在Fragmentshader中的某个位置访问和更改另一个片段的输出值吗?

例如在main()循环中,我处理所有内容,就像usualy一样,并输出一些值的颜色。但是,我还希望位于vec3(5,3,6)(世界坐标)的片段具有相同的颜色。

现在我已经在网上做了一些研究。 OpenGL站点说,片段着色器有一个片段作为输入,并有一个片段作为输出,听起来不是很有希望。 我也知道所有片段都是并行处理的。但也许可以说,如果此位置的片段尚未处理,请将此颜色写入其中并将此片段视为已处理。

我可以解释一下,如果这是可能的,如果没有,为什么这不是一个好主意。我最好的猜测是,将这个逻辑构建到着色器中,会对一般性能产生非常不利的影响。

2 个答案:

答案 0 :(得分:3)

  

我可以解释一下,如果这是可行的,如果没有,为什么这不是一个好主意。

这不是一个坏主意与好主意的问题。这根本不可能。

您最接近此功能的是ARB_fragment_shader_interlock。通过其互锁和排序保证,它允许有限的互操作。而且这个限制是......它只允许对覆盖相同像素/样本的片段进行互操作。

因此,即使此功能也不允许您写入其他像素。

你可以做的绝对最佳是使用SSBO和原子计数器让片段着色器写出什么颜色值和"世界坐标"他们想要写入,然后让第二个进程执行该缓冲区作为渲染命令或计算着色器来实际写入该数据。

答案 1 :(得分:1)

正如Nicol的回答中已经指出的那样,你不能在片段着色器中写入帧缓冲区表面的其他片段。

对您的用例的描述不够明确,无法说明最有效的方法。为了集思广益,最直接的想法是你根本不使用帧缓冲绘制表面,而是输出到图像。

如果将纹理绑定为图像,则可以使用imageStore()内置函数在片段着色器中将其写入。此函数将坐标作为参数之一,因此您可以写入所需的任何像素,也可以从同一着色器调用中写入多个像素。

根据您想要实现的目标,我还可以想象一种混合方法,您的主渲染仍然会转到帧缓冲区,但您可以在所需位置为图像写入其他像素值。然后,在第二个渲染过程中,您可以将图像的内容与主渲染组合在一起。如果数学/逻辑足够简单,可以使用混合完成组合。如果需要更复杂的组合,可以使用纹理作为初始传递的帧缓冲附件,然后使用渲染结果和额外图像作为组合传递的片段着色器的两个输入。