c++ - GLSL 照明作为平面 - 法线问题?

标签 c++ opengl glsl shader

我目前正在开发 OpenGL 框架,最近创建了一个 .ply(多边形文件格式)网格导入器。在导入器工作的情况下,我想在导入的网格上尝试一个简单的光照着色器,但遇到了问题。

网格是著名的斯坦福兔子的低分辨率版本,取自 Stanford 3D Scanning Repository并最初导入到 Blender 中以验证正确性,然后再次导出以获得 nX, nY, nZ 值,而不是 confidenceintensity。此文件可在 http://pastebin.com/raw.php?i=xRmLYN0s 找到

发生的事情是光照着色器的行为类似于平面着色器,它会根据相机方向改变颜色。图片包含在这篇文章的末尾。

着色器来自 OpenGL super 圣经,被描述为 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 属性已被确认绑定(bind)到相同的索引(ToolBox::Math::GLSL_ATTR::NORMAL又名 2) 通过 glBindAttribLocation 作为上述代码片段中的普通缓冲区。

据我所知,法线应该从文件正确传递到着色器。但是如果我在顶点着色器中设置 vFragColor.rgb = vNormal.xyz,兔子就会变成纯红色。这不太好,是吗?

那么对于着色器不工作的原因有什么想法吗?不好吗?正常不通过吗?还有别的吗?

感谢您提供的任何帮助。如果您需要更多信息,请告诉我。


图片

围绕兔子旋转:

enter image description here

enter image description here

enter image description here

设置 vFragColor.rgb = vNormal.xyz;

enter image description here

Blender 中的模型(确认其正确性)

enter image description here

最佳答案

问题出在属性绑定(bind)中。不知何故,在我的着色器解析器中,我忘记了区分正在读取的真实代码行和设置为全部大写以进行不区分大小写的比较检查的代码行。

这导致 GLSL_ATTR::NORMAL 索引绑定(bind)到 VNORMAL 而不是 vNormal。奇怪的是,这个问题在位置/颜色/纹理工作期间从未出现过。感谢@Tim 试图帮助我解决这个问题,这只是一个愚蠢的错字。

最后,兔子照常点亮了:

enter image description here

关于c++ - GLSL 照明作为平面 - 法线问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11978794/

相关文章:

opengl - GLSL gl_Position 中的第四维是什么?

c++ - Win32 无窗口应用程序 - 等待程序退出

c++ - 使用 boost 读取执行命令的结果(C++ 库)

delphi - OpenGL:帮助进行相机变换

opengl - glsl片段着色器如何从每个顶点获取非插值数据

c++ - 使用 Intel HD 和 NVidia GPU 的 OpenGL 程序

c++ - BOOST_CLASS_EXPORT 放在哪里进行 boost::serialization?

c++ - 矩阵模板,内存泄漏

c++ - 我需要为 OpenGL 3.3 Core 使用着色器吗?

java - OpenGL/着色器/矩阵 : Weird scaling of the shape after a rotation of the view matrix