在 OpenGL 顶点着色器中,唯一被视为动态统一的内置输入是gl_DrawID
。我可以猜测,不进行动态统一的决定gl_InstanceID
是为了允许实现将来自不同实例的顶点分组到单个顶点着色器扭曲(/波前/其他)中。然而,众所周知,每个实例具有少量顶点的实例化绘制对性能不利,因为没有主要的桌面 GPU 供应商实际上将多个实例分组到单个扭曲中(这导致每个顶点很少的许多实例的扭曲占用率较低) )。这似乎意味着在实践中,gl_InstanceID
很可能会动态统一。不制作的理由是什么gl_InstanceID
(gl_BaseInstance
以及gl_BaseVertex
) 动态统一表达式?是否有任何 GPU 可以实际对每个波前的多个实例进行分组,或者在编写规范时是否存在?
OpenGL 中的动态统一表达式被定义为对于同一调用组中的所有调用具有相同值的表达式。渲染模式下的调用组是由单个绘制命令引起的所有着色器的所有调用的组合。常规绘制命令 (
glDrawElements
,glDrawArrays
) 和实例绘制命令 (glDrawElementsInstanced
,glDrawArraysInstanced
, ...) 被视为单个绘制命令,与多绘制命令相反,多绘制命令的每个子命令都有一个单独的调用组。GPU 如何将渲染命令分组为扭曲(OpenGL 没有渲染调用的概念),在这里并没有真正发挥作用,因为这不是识别动态统一表达式的决定因素。
根据这些定义,应该很容易理解为什么
gl_InstanceID
不能动态统一,除非只有一个实例。请注意,上述调用组的定义仅对渲染模式有效。计算模式有它自己的定义。