在 GLSL 中使用 int 时渲染中断
Rendering breaks when using an int in GLSL
我正在为延迟渲染器渲染光球,并且正在切换到实例化以获得更好的性能。我有以下顶点着色器:
in vec3 position;
uniform int test_index;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix[256];
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix[test_index] * vec4(position, 1.0);
}
我使用
将矩阵上传到着色器
val location = glGetUniformLocation(programId, "modelMatrix[$i]")
glUniformMatrix4fv(location, false, buf)
当我在索引中使用 int
制服(出于调试目的硬编码为 0
)时,球体消失了,除非我剪辑到几何体中(在这种情况下它呈现为白色圆圈)。当我使用 gl_InstanceID
作为我的索引时,也会发生同样的情况。
奇怪的是,我注意到当我将 int
从顶点传递到片段着色器并将它用于完全不同的东西时,也会出现问题,无论我使用什么作为索引。
当我在着色器中硬编码 modelMatrix[0]
而不是 modelMatrix[test_index]
时,问题立即消失并且渲染完全正常。
我有一个不同的着色器(用于骨骼动画),它以完全相同的方式上传一个 mat4 统一数组,也用一个 int 进行索引,但我没有遇到这样的问题...
我真的不知道该怎么做,所以非常感谢任何关于如何调试它的建议。我在 Kotlin+LWJGL
上使用 OpenGL 3.3
编辑:这可能与制服无关。以下也 not 工作:
int i = 0;
gl_Position = projectionMatrix * viewMatrix * modelMatrix[i] * vec4(position, 1.0f);
OpenGL 对可以使用的制服数量有限制。这同样适用于属性(但这不是这里的问题)。 256个矩阵的数组很可能超出允许的数量。
代码仅在使用 int 统一时中断的原因是 glsl 编译器在后台进行了大量优化,例如,删除未使用的统一。因此,如果您在着色器中对数组位置进行硬编码,编译器会注意到只使用了一个矩阵,并且可能会删除所有其他矩阵。
当您需要比 OpenGL 允许的更多的统一时,您必须使用统一缓冲区对象 (UBO) 或着色器存储缓冲区 (SSBO)。
我正在为延迟渲染器渲染光球,并且正在切换到实例化以获得更好的性能。我有以下顶点着色器:
in vec3 position;
uniform int test_index;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix[256];
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix[test_index] * vec4(position, 1.0);
}
我使用
将矩阵上传到着色器val location = glGetUniformLocation(programId, "modelMatrix[$i]")
glUniformMatrix4fv(location, false, buf)
当我在索引中使用 int
制服(出于调试目的硬编码为 0
)时,球体消失了,除非我剪辑到几何体中(在这种情况下它呈现为白色圆圈)。当我使用 gl_InstanceID
作为我的索引时,也会发生同样的情况。
奇怪的是,我注意到当我将 int
从顶点传递到片段着色器并将它用于完全不同的东西时,也会出现问题,无论我使用什么作为索引。
当我在着色器中硬编码 modelMatrix[0]
而不是 modelMatrix[test_index]
时,问题立即消失并且渲染完全正常。
我有一个不同的着色器(用于骨骼动画),它以完全相同的方式上传一个 mat4 统一数组,也用一个 int 进行索引,但我没有遇到这样的问题...
我真的不知道该怎么做,所以非常感谢任何关于如何调试它的建议。我在 Kotlin+LWJGL
上使用 OpenGL 3.3编辑:这可能与制服无关。以下也 not 工作:
int i = 0;
gl_Position = projectionMatrix * viewMatrix * modelMatrix[i] * vec4(position, 1.0f);
OpenGL 对可以使用的制服数量有限制。这同样适用于属性(但这不是这里的问题)。 256个矩阵的数组很可能超出允许的数量。
代码仅在使用 int 统一时中断的原因是 glsl 编译器在后台进行了大量优化,例如,删除未使用的统一。因此,如果您在着色器中对数组位置进行硬编码,编译器会注意到只使用了一个矩阵,并且可能会删除所有其他矩阵。
当您需要比 OpenGL 允许的更多的统一时,您必须使用统一缓冲区对象 (UBO) 或着色器存储缓冲区 (SSBO)。