我目前正在研究一个 OpenGL 框架,最近创建了一个.ply
(多边形文件格式)网格导入器。随着导入器的工作,我想在导入的网格上尝试一个简单的光照着色器,但遇到了问题。
该网格是著名的斯坦福兔子的低分辨率版本,取自斯坦福 3D 扫描存储库,最初被导入 Blender 以验证正确性,然后再次导出以获得与和nX, nY, nZ
相对的值。该文件可在http://pastebin.com/raw.php?i=xRmLYN0s找到confidence
intensity
正在发生的事情是光照着色器就像一个平面着色器,它会根据相机方向改变颜色。图片包含在这篇文章的末尾。
着色器来自 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中的模型(确认其正确性)