法线贴图中的光照不正确
我的 OpenGL 游戏引擎中有一个法线贴图,我意识到我的法线贴图着色器(以及视差贴图着色器)的光照存在问题。无论光在哪里,光总是来自右边。我正在使用切线空间着色器,我不确定我传递的内容是否正确。
这是我正在使用的法线贴图:
这是渲染:
光线似乎来自坐标 3,0,3,但其实际位置是 -3,0,3
任何想法。
着色器:
[vert]
attribute vec3 intan;
varying vec3 lightDir;
varying vec3 viewDir;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * intan);
vec3 b = cross(n, t) ;
mat3 tbnMatrix = mat3(t.x, b.x, n.x,
t.y, b.y, n.y,
t.z, b.z, n.z);
lightDir = (gl_LightSource[1].position.xyz - vertexPos) / 1000.;
lightDir = tbnMatrix * lightDir;
viewDir = -vertexPos;
//viewDir =
viewDir = tbnMatrix * viewDir;
}
[frag]
uniform sampler2D tex;
uniform sampler2D nor;
varying vec3 lightDir;
varying vec3 viewDir;
const vec4 d = vec4(0.19225,0.19225,0.19225,1.0);
const vec4 a = vec4(0.50754,0.50754,0.50754,1.0);
const vec4 s = vec4(0.508273,0.508273,0.508273,1.0);
void main()
{
vec3 l = lightDir;
float atten = max(0.0, 1.0 - dot(l, l));
l = normalize(l);
vec3 n = normalize(texture2D(nor, gl_TexCoord[0].st).xyz * 2.0 - 1.0);
vec3 v = normalize(viewDir);
vec3 h = normalize(l + v);
float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);
vec4 ambient = a * atten;
vec4 diffuse = d * nDotL * atten;
vec4 specular = s * power * atten;
vec4 color = ambient + diffuse + specular;
gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st);
}
I have a normal map in my OpenGL game engine and I realized that my normal map shader (and parallax map shader for that matter) have a problem with the lighting. Regardless of where the light is,the light always comes from the right. I am using a tangent space shader and I'm not sure if what I am passing in is correct.
This is the Normal Map That I Am Using:
And here is the render:
The light appears to be coming from the coordinate 3,0,3 but its actual location is -3,0,3
Any Ideas.
Shaders:
[vert]
attribute vec3 intan;
varying vec3 lightDir;
varying vec3 viewDir;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * intan);
vec3 b = cross(n, t) ;
mat3 tbnMatrix = mat3(t.x, b.x, n.x,
t.y, b.y, n.y,
t.z, b.z, n.z);
lightDir = (gl_LightSource[1].position.xyz - vertexPos) / 1000.;
lightDir = tbnMatrix * lightDir;
viewDir = -vertexPos;
//viewDir =
viewDir = tbnMatrix * viewDir;
}
[frag]
uniform sampler2D tex;
uniform sampler2D nor;
varying vec3 lightDir;
varying vec3 viewDir;
const vec4 d = vec4(0.19225,0.19225,0.19225,1.0);
const vec4 a = vec4(0.50754,0.50754,0.50754,1.0);
const vec4 s = vec4(0.508273,0.508273,0.508273,1.0);
void main()
{
vec3 l = lightDir;
float atten = max(0.0, 1.0 - dot(l, l));
l = normalize(l);
vec3 n = normalize(texture2D(nor, gl_TexCoord[0].st).xyz * 2.0 - 1.0);
vec3 v = normalize(viewDir);
vec3 h = normalize(l + v);
float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);
vec4 ambient = a * atten;
vec4 diffuse = d * nDotL * atten;
vec4 specular = s * power * atten;
vec4 color = ambient + diffuse + specular;
gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为 intan 指定法线贴图“右”指向的方向。那么那个叉积就是错误的。如果 n 指向曲面外且向右,则 b(inormal) 指向下方。
请注意,如果变换法线和切线,然后对结果进行叉积,或者先进行叉积并变换结果,这没有什么区别。
你为什么不把它正常化呢?除以 1000 没有意义。
I suppose
intan
designates the direction in which the normal map "right" points. Then that cross product is wrong. If n points out of the surface and intan to the right, then b(inormal) points downwards.Note that it makes no difference if you transform normal and tangent and then do the crossproduct of the result or do the crossproduct first and transform the result.
Why don't you just normalize that? That division by 1000 doesn't make sense.