3

我有一种情况,我有两个特定的着色器:

第一个着色器从场景中的所有对象投射阴影并渲染到单个全屏 8 位阴影纹理。glsl 代码非常短。

第二个着色器对 g 缓冲区执行延迟光照计算,并渲染到单个全屏 32 位纹理缓冲区。它使用了几种全屏纹理(32 位位置、16 位法线、32 位漫反射、8 位镜面反射、8 位阴影)。glsl 代码也很冗长。

如您所见,对于每个灯光,这两个着色器必须随后执行。A 然后 B,A 然后 B,A 然后 B。这会导致大量交换。

我读过着色器交换具有一些相对较高的开销,但我不熟悉 GPU 如何处理仅两个着色器之间的交换。

这两个着色器程序是否会被有效地缓存到不应该成为问题的程度?

我应该组合这两个着色器并使用 glDrawBuffers() 直接输出吗?如果我将它们结合起来,从前一个 g-buffer 照明阶段加载的 5 个纹理将在下一个阴影投射阶段变得陈旧,这会导致任何性能开销吗?

4

1 回答 1

4

这两个着色器程序是否会被有效地缓存到不应该成为问题的程度?

问题不在于缓存,而是更改着色器会刷新 GPU 执行管道。管道和分支预测器需要几十个时钟周期才能适应新切换到的着色器。

我应该组合这两个着色器并使用 glDrawBuffers() 直接输出吗?

在延迟着色器设置中,您是否可以在没有太多问题的情况下做到这一点?确实!

于 2013-04-19T09:05:08.717 回答