无法向Shader传递Uniform值:矩阵全为0、纹理绑定异常求助
问题描述
尝试给Shader设置Uniform值,但仅能获取到之前使用过的纹理(slot 0),所有矩阵都被填充为0。
CPU端代码片段
glUseProgram(VSSMTestShaderProgram); glUniform1i(glGetUniformLocation(VSSMTestShaderProgram, "depthMap"), 10); glUniform1i(glGetUniformLocation(VSSMTestShaderProgram, "depth2Map"), 11); transformLoc = glGetUniformLocation(VSSMTestShaderProgram, "transformToScreenSpace"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(view_trans)); glm::mat4 shadowProj = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.01f, 30.0f); glm::mat4 shadowTransform = shadowProj * glm::lookAt(glm::vec3(5.0,5.0,5.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0)); transformLoc = glGetUniformLocation(VSSMTestShaderProgram, "transformToLightSpace"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(shadowTransform)); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
Shader代码
顶点着色器
//shader for VSSM shadows #version 330 core layout (location = 0) in vec3 aPos; out vec4 LightSpaceCoord; uniform mat4 transformToScreenSpace; uniform mat4 transformToLightSpace; void main() { gl_Position = transformToScreenSpace * vec4(aPos.x, aPos.y, aPos.z, 1.0f); LightSpaceCoord = transformToLightSpace * vec4(aPos.x, aPos.y, aPos.z, 1.0f); }
片段着色器
#version 330 core out vec4 FragColor; in vec4 LightSpaceCoord; uniform sampler2D depthMap; uniform sampler2D depth2Map; void main() { //vec2(LightSpaceCoord.x/2+0.5, LightSpaceCoord.y/2+0.5) float lightDepth = texture(depthMap, vec2(0.1, 0.1)).r; if(lightDepth<LightSpaceCoord.z){ FragColor = vec4(lightDepth, lightDepth, lightDepth, 1.0); }else{ FragColor = gl_FragColor; } }
问题现象截图
矩阵设置异常

纹理设置异常

解决方法
检查Uniform有效性
每次调用glGetUniformLocation后必须检查返回值是否为-1:- 片段着色器中
depth2Map未被引用,会被编译器优化剔除,导致glGetUniformLocation返回-1,设置无效。 - 确保Uniform名和Shader中完全一致(大小写敏感)。
- 片段着色器中
修正纹理单元设置逻辑
OpenGL纹理单元从0开始索引,使用10、11时需补充绑定步骤:glActiveTexture(GL_TEXTURE10); glBindTexture(GL_TEXTURE_2D, depthMapTextureID); glActiveTexture(GL_TEXTURE11); glBindTexture(GL_TEXTURE_2D, depth2MapTextureID);仅设置Uniform的纹理单元值但不绑定纹理,采样必然出错。同时可通过
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits)查询显卡支持的最大纹理单元数,确认10、11在范围内。排查矩阵传递问题
- 确认
view_trans矩阵已正确初始化,不是全0矩阵。 - glm矩阵默认是列主序,
glUniformMatrix4fv第三个参数传GL_FALSE是正确的,确保未手动转置矩阵。
- 确认
修复片段着色器废弃变量
GLSL 330 core版本已废弃gl_FragColor,需替换为自定义输出变量:// 替换原else分支内容 FragColor = vec4(1.0, 1.0, 1.0, 1.0);使用废弃变量可能导致着色器运行异常,进而影响Uniform传递。
内容的提问来源于stack exchange,提问作者minisparks
相关产品推荐
相关产品推荐

