在 OpenGL 中编写片段着色器时,可以在编译时常量、统一 变量或可变 变量上进行分支。
分支的性能如何取决于硬件和驱动程序的实现,但通常在编译时间常量上的分支通常是免费的,并且在uniform上的分支比在varying上更快em>.
在 varying 的情况下,光栅化器仍然必须为每个片段插入变量,并且必须在每个系列执行时决定分支,即使 varying 的值相同对于当前图元中的每个片段。
我想知道的是,是否有任何图形 API 或扩展允许某些片段着色器分支,每个光栅化图元只执行一次(或者在平铺渲染的情况下每个图元每个图元一次)?
最佳答案
动态分支仅在导致 divergence of instances executing at the same time 时才昂贵.插入“变化”的成本微不足道。
此外,不同的 GPU 处理图元光栅化的方式不同。一些 GPU 确保片段着色器的波前仅包含在同一图元上执行的实例。在这些 GPU 上,基于不改变每个基元的值的分支会很快。
但是,其他 GPU 会将来自不同基元的实例打包到相同的波阵面中。在这些 GPU 上,如果不同基元的值不同,就会发生分歧。分歧有多大?这取决于您在原语中获得多个实例的频率。如果您的许多图元在光栅化空间中都很小,那么与您有很多大图元相比,您会得到更多的发散。
将来自不同基元的实例打包到一个波前的 GPU 正试图最大限度地利用它们的内核。这是一个权衡:您正在最小化必须执行的波前总数,但发散的特定原因(数据在基元内保持不变但在它们之间不是)将受到惩罚。
无论如何,尽可能避免分歧。但是如果你的算法需要它……那么你的算法需要它,你得到的性能就是你得到的性能。您能做的最好的事情就是让 GPU 知道“变化”将通过使用 flat
插值来保持每个基元不变。
关于opengl - 是否有任何图形 API 允许高效的每个图元分支?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70224951/