GLSL法线贴图(0.0 Lambert点亮的区域)

时间:2013-05-14 14:00:12

标签: opengl glsl shader assimp bump-mapping

当我使用模型的法线时,结果很好(有暗区和亮区,正如我期望的简单朗伯漫反射着色器)

但是当我使用普通地图时,黑暗区域会亮起来!

我想使用法线贴图并仍然像这些示例一样获得正确的漫反射光照

这里是带有和没有法线贴图的代码

这是使用法线贴图的代码

顶点着色器

varying vec3 normal,lightDir;
attribute vec3 vertex,normalVec,tangent;
attribute vec2 UV;

void main(){

gl_TexCoord[0] = gl_TextureMatrix[0] * vec4(UV,0.0,0.0);
normal = normalize (gl_NormalMatrix * normalVec);
vec3 t = normalize (gl_NormalMatrix * tangent);
vec3 b = cross (normal, t);
vec3 vertexPosition = normalize(vec3(gl_ModelViewMatrix * vec4(vertex,1.0)));
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, normal);
lightDir = normalize (v);
lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);
gl_Position = gl_ModelViewProjectionMatrix*vec4(vertex,1.0);
}

片段着色器

vec4 computeDiffuseLight (const in vec3 direction, const in vec4 lightcolor, const in vec3 normal, const in vec4 mydiffuse){

float nDotL = dot(normal, direction);
vec4 lambert = mydiffuse * lightcolor * max (nDotL, 0.0);
return lambert;
}

varying vec3 normal,lightDir;
uniform sampler2D textures[8];

void main(){
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
vec4 diffuse = computeDiffuseLight (lightDir, vec4(1,1,1,1) , normalVector, vec4(0.7,0.7,0.7,0));
gl_FragColor = diffuse ;
}

注意:实际法线贴图的工作正常,如镜面高光

中所示

我使用Assimp加载模型(md5mesh)并使用Assimp计算切线,然后将其作为属性发送到着色器

这是指向问题的代码和屏幕截图的链接

https://dl.dropboxusercontent.com/u/32670019/code%20and%20screenshots.zip

是代码中的问题还是我有误解?

更新了代码和屏幕截图

https://dl.dropboxusercontent.com/u/32670019/updated%20code%20and%20screenshots.zip

现在法线贴图与漫反射一起使用,但仅漫反射不正确

1 个答案:

答案 0 :(得分:0)

如需回答,请参阅下文。

快速(可能是错误的)观察: 这条线

vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
片段着色器中的

正确地重新调整法线以允许负值。如果您的法线贴图不正确,则可能会出现负值(如果您不想要它们的Y轴)。法线中的负值可能导致逆光。

我向你提问:你的法线贴图是否正确?

答案:经过一番讨论后我们发现了问题,我编辑了这篇文章以保持线程干净,Darko问题的解决方案在这里的评论中。它归结为未初始化的变化,称为lightDir。

原始评论:

lightDir = normalize(v); lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);这很奇怪,你立即覆盖它,这是错的吗?你似乎没有保持正确翻译的lightDir ...或者我是疯了...这个lightDir是一个变化,但你根本没有设置它。所以你从零开始计算一个v向量?