当我使用模型的normal时,结果很好(有暗区和亮区,正如我期望的那样从一个简单的lambert漫反射着色器)
但是当我使用法线贴图时,黑暗的区域会被点亮!
我想使用法线贴图,仍然像这些例子一样得到正确的漫射照明
下面是有和没有法线映射的代码
,这里是使用法线映射
的代码顶点着色器
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现在法线贴图与漫射一起工作,但是单独的漫射是不正确的
回答,见下文。
快速观察(可能错误):
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
片段着色器中的正确地重新缩放法线以允许负值。如果你的法线贴图是不正确的,负值可能会出现在你不想要的地方(我假设你的Y轴)。正常值的负值会导致反向照明。
我的问题是:你的法线贴图正确吗?
ANSWER:经过一些讨论,我们发现了这个问题,我编辑了这篇文章以保持线程干净,Darko问题的解决方案在这里的评论中。它变成了未初始化的变量lightDir。
原始评论:lightDir = normalize (v);lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);这很奇怪,你马上就重写了,这有错吗?你似乎没有保持正确翻译的lightDir…还是我疯了?这个lightDir是可变的,但你根本不用设置它。所以你从无到有计算出一个v向量?