【发布时间】:2014-03-26 11:44:47
【问题描述】:
我正在世界空间坐标中实现法线/凹凸贴图(我发现那些更容易使用)并且我的照明在没有法线贴图的情况下工作得很好,但是在引入法线贴图(以及使用 TBN 矩阵计算的新向量)时我的照明的镜面反射组件已关闭。
镜面反射分量不在相机和灯光之间,因此出现了问题。但是,查看我的代码我找不到任何问题。切线和双切线来自 ASSIMP 对象加载器,而 eyePos 和 lightPos 也在世界坐标中。
由于高光部分的光照看起来正确(显示了凹凸贴图),我认为它与切线空间变换有关?
这是一个演示问题的图片:
顶点着色器:
#version 330
layout (location = 0) in vec4 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 bitangent;
layout(location = 5) in vec2 texCoord;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform vec3 lightPos;
uniform vec3 eyePos;
out vec3 Position;
out vec2 TexCoord;
out vec3 tangentLightDir;
out vec3 tangentViewDir;
void main()
{
gl_Position = projection * view * model * vertex;
// Position
Position = vec3(model * vertex);
// Normal
mat3 normalMat = transpose(inverse(mat3(model)));
Normal = normalize(normalMat * normal);
// Texture
TexCoord = texCoord;
// Normal mapping
mat3 TBN = mat3(tangent, bitangent, Normal);
TBN = transpose(TBN);
// Get direction vectors:
vec3 lightDir = normalize(lightPos - Position);
vec3 viewDir = normalize(eyePos - Position);
// Now transform them to tangent space
tangentLightDir = TBN * lightDir;
tangentViewDir = TBN * viewDir;
}
片段着色器:
#version 330
in vec3 Position;
in vec2 TexCoord;
in vec3 tangentLightDir;
in vec3 tangentViewDir;
uniform sampler2D texture0;
uniform sampler2D texture_normal;
out vec4 outColor;
void main()
{
// defaults
vec4 ambient = vec4(0.1);
vec4 diffuse = vec4(0.4);
vec4 specular = vec4(0.5);
vec4 texColor = texture(texture0, TexCoord);
// Phong shading
vec3 LightDir = normalize(tangentLightDir);
vec3 Norm = normalize(texture(texture_normal, TexCoord).xyz * 2.0 - 1.0);
vec3 ViewDir = normalize(tangentViewDir);
vec3 ReflectDir = reflect(-LightDir,Norm);
float specularContribution = pow(max(dot(ViewDir, ReflectDir), 0.0), 32);
// Calculate diffuse component
vec4 I = diffuse * max(dot(LightDir, Norm), 0.0);
diffuse = clamp(I, 0.0, 1.0);
// Calculate specular component
specular = specular * specularContribution;
outColor = texColor * (diffuse + specular + ambient);
}
【问题讨论】:
-
你把eyePos和lightPos转换成屏幕坐标了吗?
-
@Snowfish:它们在世界/全球空间坐标中,因为所有计算都是在世界/全球空间中完成的,这应该是正确的,对吧?
-
我的错。看起来确实是 TBN 的问题。
-
你通过 normalMat 转换法线,但是你对切线和双切线没有做同样的事情,所以你的 TBN 不正确。