问题

是否可以在第一个着色器程序中计算某些内容(例如,从字空间的屏幕空间坐标)并在另一个着色器程序中访问这些结果?

可能的解决方案



放弃多着色器程序体系结构并创建一个组合的着色器程序
以某种方式将结果保存到缓冲区对象(我无法除了计算着色器外,找不到其他方法。
渲染纹理并读取纹理

是否有更好的解决方案?

#1 楼

是的,您可以,例如,这就是延迟渲染的工作方式。为此,您将在一次通过中渲染纹理,在openGL中,这将通过FBO,然后将该纹理作为输入提供给下一个通过/着色器。

评论


$ \ begingroup $
有点限制吗?我的意思是,IMO,纹理并不是一般用于传递数据的最合适的数据存储(但是我是计算机图形学的新手,也许我必须习惯它)。
$ \ endgroup $
–BPiek
16年8月2日在6:28

$ \ begingroup $
纹理只是普通的缓冲区,尽管在片段着色器中,我们使用花哨的sampler2D进行过滤/等操作来读取纹理。您可以使用计算着色器以原始格式阅读更多内容,并跳过纹理采样器阶段。
$ \ endgroup $
–PaulHK
16年8月2日在6:30

$ \ begingroup $
有几种选择。除非您需要在屏幕空间中计算结果(例如在延迟渲染中),否则渲染到纹理可能是最直接的方法,也是一种浪费,因为您要在进行任何计算之前对几何体进行栅格化。有变换反馈,您可以在顶点或几何着色器的输出到达光栅化器之前将其拉出,然后将其写回缓冲区,这可能对您提到的用例很有用,但我自己还没有尝试过。否则,计算着色器是必经之路,一旦您习惯了它们,它们就不会那么吓人了;-)
$ \ endgroup $
– russ
16年8月5日在17:38

#2 楼

尽管其他答案为实现所需的功能提供了可能的技术,但如果在下一个渲染步骤中需要将其作为VBO(即顶点属性)来将其渲染为纹理,则并非总是最好的方法(需要读取进入PBO并获取一些索引/坐标/大小调整魔术或获取顶点纹理)。

这种方法可以更准确地表示您的第二个点,并且在需要从缓冲区转换为缓冲区时会更好就是所谓的转换反馈(或DirectX世界中的流输出)。但是,这需要OpenGL 3 / DirectX 10硬件(但是,计算着色器不一定需要GL4 / DX11)。当您的用例实际上只是要将一堆顶点/图元转换为一堆顶点/图元时,它的同步混乱也比使用任意着色器存储缓冲区的计算着色器少。

它基本上,您可以在顶点(或基本图元)处理步骤之后,在光栅化之前挂接到渲染管线中,并将直接计算的每个顶点值写到缓冲区对象中(然后可以在下一步中用作顶点属性) )。因此,它也不会将任何内容拖入帧缓冲区。您只需指定一堆varying/out变量以及如何将它们格式化为缓冲区并将缓冲区绑定到相应的绑定点即可。您还可以使用查询来收集有关编写了多少个基本体的信息(因为几何体着色器可以动态更改),或者在更高版本中,可以直接渲染结果而无需同步。有关更多详细信息,请参见上面的Wiki文章。

连同几何体着色器(TF硬件也应具有)以及其更改基本体类型或移除/添加顶点的能力,这将成为转换几何体的有用工具,但是您认为适合进行进一步的渲染阶段的准备。当然,如果在特定用例中确实可以为您带来任何收益,则必须对其进行评估,尤其是如果您确实只是在进行简单的顶点转换时。