我目前正在开发一个OpenGL框架,最近创建了一个.ply
(多边形文件格式)网格导入器。在导入器工作的情况下,我想在导入的网格物体上尝试一个简单的灯光着色器,但遇到了问题。
网格是来自Stanford 3D Scanning Repository的着名斯坦福兔子的低分辨率版本,最初导入Blender以验证正确性,然后再次导出以获得nX, nY, nZ
值而不是{}到confidence
和intensity
。此文件位于http://pastebin.com/raw.php?i=xRmLYN0s
正在发生的事情是,灯光着色器的作用类似于平面着色器,可根据相机方向改变颜色。图片包含在本文末尾。
着色器来自OpenGL超级圣经,被描述为Simple diffuse, directional, and vertex based light
:
顶点
#version 140
uniform mat4 mvMatrix;
uniform mat4 pMatrix;
uniform vec4 vColor;
in vec4 vVertex;
in vec3 vNormal;
out vec4 vFragColor;
void main( void )
{
mat3 mNormalMatrix;
mNormalMatrix[0] = mvMatrix[0].xyz;
mNormalMatrix[1] = mvMatrix[1].xyz;
mNormalMatrix[2] = mvMatrix[2].xyz;
vec3 vNorm = normalize(mNormalMatrix * vNormal);
vec3 vLightDir = vec3(0.0, 0.0, 1.0);
float fDot = max(0.0, dot(vNorm, vLightDir));
vFragColor.rgb = vColor.rgb * fDot;
vFragColor.a = vColor.a;
gl_Position = ( pMatrix * mvMatrix ) * vVertex;
}
片段
#version 140
in vec4 vFragColor;
void main( void )
{
gl_FragColor = vFragColor;
}
这可能与法线有关吗?我已经验证它们是从模型文件中正确提取的,然后将它们输入VAO:
glBindVertexArray( m_VAO );
glEnableVertexAttribArray( ToolBox::Math::GLSL_ATTR::NORMAL );
glBindBuffer( GL_ARRAY_BUFFER, m_NormalBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * num_elements, normals, GL_STATIC_DRAW );
glVertexAttribPointer( ToolBox::Math::GLSL_ATTR::NORMAL, 3, GL_FLOAT, GL_FALSE, 0, ( const GLvoid* )0 );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
这与用于空间(x,y,z)信息的VAO相同,并且过去曾用于颜色和纹理值。此外,着色器由自定义ShaderManager类解析,vNormal
属性已确认通过ToolBox::Math::GLSL_ATTR::NORMAL
绑定到同一索引(2
又名glBindAttribLocation
)上面代码段中的普通缓冲区。
据我所知,法线应该正确地从文件传递到着色器。但是如果我在顶点着色器中设置vFragColor.rgb = vNormal.xyz
,那么兔子就会变成红色。那不好,是吗?
那么为什么着色器不起作用的任何想法?这不好吗?正常没有通过吗?还有别的吗?
感谢您提供的任何帮助。如果您需要更多信息,请告诉我。
图片
围绕兔子旋转:
设置vFragColor.rgb = vNormal.xyz;
Blender中的模型(确认其正确性)
答案 0 :(得分:2)
问题出在属性绑定中。不知何故,在我的着色器解析器中,我忘了区分正在读取的代码行和用于不区分大小写的比较检查的全部大写代码。
这导致GLSL_ATTR::NORMAL
索引绑定到与VNORMAL
相对的vNormal
。奇怪的是,这个问题在位置/颜色/纹理工作期间从未重新出现过。感谢@Tim试图帮助我解决这个简直是一个愚蠢错字的问题。
最后,兔子照亮了它的意思: