OpenGL中顶点与法线的关联机制及实心模型全黑问题排查
问题:3D模型实心显示模式下光照失效(全黑)
原本应用可正常以线框模式显示3D模型,切换为实心显示(将glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)改为glPolygonMode(GL_FRONT_AND_BACK, GL_FILL))后,因缺少法线与光照设置,模型无法正确呈现光照效果。已做以下修改,但模型显示为实心却全黑,光照未生效:
已完成的修改
a) 编写实心模型的片段着色器
#version 130 in vec3 Normal; in vec3 fpos; out vec4 fragment_color; const vec3 lightPos = vec3(0.0,0.0,5.0); const vec3 diffColor = vec3(1.0,0.5,0.0); const vec3 specColor = vec3(1.0,1.0,1.0); void main () { vec3 normal = normalize(Normal); vec3 viewDir = normalize(-fpos); if (dot(normal, viewDir) < 0.0) normal *= -1.0; vec3 lightDir = normalize(lightPos - fpos); float lamb = max(dot(lightDir, normal), 0.0); float spec = 0.0; if (lamb > 0.0) { vec3 refDir = reflect(-lightDir, normal); float specAngle = max(dot(refDir, viewDir), 0.0); spec = pow(specAngle, 4.0); } fragment_color = vec4(lamb * diffColor + spec * specColor, 1.0); }
b) 添加法线数据加载代码
原有顶点坐标设置代码:
glBindVertexArray(entity->m_gl3Element.VAO); glBindBuffer(GL_ARRAY_BUFFER,entity->m_gl3Element.coordVBO); glBufferData(GL_ARRAY_BUFFER,m_vertexArray.size()*sizeof(float),m_vertexArray.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0);
新增的法线加载代码:
glBindBuffer(GL_ARRAY_BUFFER,entity->m_gl3Element.normalVBO); glBufferData(GL_ARRAY_BUFFER, normalArray.size()*sizeof(float),normalArray.data(), GL_STATIC_DRAW); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER,entity->m_gl3Element.normalVBO); glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void*)0);
最后调用glBindVertexArray(0),后续通过glDrawArrays绘制模型。
疑问与问题点
- 修改后模型为实心但全黑,光照完全未生效
- 不清楚法线与顶点坐标的关联逻辑:是否是通过
glEnableVertexAttribArray(2)和glVertexAttribPointer(2,...)中的索引「2」实现关联?OpenGL是否默认识别索引「2」为法线? - 法线数据来自磁盘加载的3D模型,本身数据应该无问题
内容的提问来源于stack exchange,提问作者Elmi
相关产品推荐
相关产品推荐

