切线空间法线贴图 - 着色器完整性检查

问题描述:

我从我的切线空间法线贴图着色器得到了一些非常怪异的结果:)。在这里展示的场景中,茶壶和格子墙被我普通的Phong-Blinn着色器遮盖(显然,茶壶背面剔除使它具有轻微的短暂外观和感觉:-))。我一直在努力,在正常映射添加到球体,迷幻的结果:切线空间法线贴图 - 着色器完整性检查

Incorrect Normal Mapping on Sphere

的光从右边过来(只是为黑色斑点可见)。我使用的是在球体上的法线贴图看起来是这样的:

Normal Map

我使用AssImp处理输入的机型,所以它会自动计算切线和双向法线每个顶点我。

像素和顶点着色器如下。我不太确定发生了什么问题,但如果切线基础矩阵有些错误,我不会感到惊讶。我假设我必须将东西计算到眼睛空间中,然后将眼睛和光线矢量转换为切线空间,并且这是正确的方法。请注意,灯光位置已经进入着色器中。

// Vertex Shader 
#version 420 

// Uniform Buffer Structures 

// Camera. 
layout (std140) uniform Camera 
{ 
    mat4 Camera_Projection; 
    mat4 Camera_View; 
}; 

// Matrices per model. 
layout (std140) uniform Model 
{ 
    mat4 Model_ViewModelSpace; 
    mat4 Model_ViewModelSpaceInverseTranspose; 
}; 

// Spotlight. 
layout (std140) uniform OmniLight 
{ 
    float Light_Intensity; 

    vec3 Light_Position;   // Already in view space. 
    vec4 Light_Ambient_Colour; 
    vec4 Light_Diffuse_Colour; 
    vec4 Light_Specular_Colour; 
}; 

// Streams (per vertex) 
layout(location = 0) in vec3 attrib_Position; 
layout(location = 1) in vec3 attrib_Normal; 
layout(location = 2) in vec3 attrib_Tangent; 
layout(location = 3) in vec3 attrib_BiNormal; 
layout(location = 4) in vec2 attrib_Texture; 

// Output streams (per vertex) 
out vec3 attrib_Fragment_Normal; 
out vec4 attrib_Fragment_Position; 
out vec3 attrib_Fragment_Light; 
out vec3 attrib_Fragment_Eye; 

// Shared. 
out vec2 varying_TextureCoord; 

// Main 
void main() 
{ 
    // Compute normal. 
    attrib_Fragment_Normal = (Model_ViewModelSpaceInverseTranspose * vec4(attrib_Normal, 0.0)).xyz; 

    // Compute position. 
    vec4 position = Model_ViewModelSpace * vec4(attrib_Position, 1.0); 

    // Generate matrix for tangent basis. 
    mat3 tangentBasis = mat3( attrib_Tangent, 
           attrib_BiNormal, 
           attrib_Normal); 

    // Light vector. 
    attrib_Fragment_Light = tangentBasis * normalize(Light_Position - position.xyz); 

    // Eye vector. 
    attrib_Fragment_Eye = tangentBasis * normalize(-position.xyz); 

    // Return position. 
    gl_Position = Camera_Projection * position; 
} 

...和像素着色器看起来是这样的:

// Pixel Shader 
#version 420 

// Samplers 
uniform sampler2D Map_Normal; 

// Global Uniforms 

// Material. 
layout (std140) uniform Material 
{ 
    vec4 Material_Ambient_Colour; 
    vec4 Material_Diffuse_Colour; 
    vec4 Material_Specular_Colour; 
    vec4 Material_Emissive_Colour; 

    float Material_Shininess; 
    float Material_Strength; 
}; 

// Spotlight. 
layout (std140) uniform OmniLight 
{ 
    float Light_Intensity; 

    vec3 Light_Position;  
    vec4 Light_Ambient_Colour; 
    vec4 Light_Diffuse_Colour; 
    vec4 Light_Specular_Colour; 
}; 

// Input streams (per vertex) 
in vec3 attrib_Fragment_Normal; 
in vec3 attrib_Fragment_Position; 
in vec3 attrib_Fragment_Light; 
in vec3 attrib_Fragment_Eye; 

// Shared. 
in vec2 varying_TextureCoord; 

// Result 
out vec4 Out_Colour; 

// Main 
void main(void) 
{ 
    // Compute normals. 
    vec3 N = normalize(texture(Map_Normal, varying_TextureCoord).xyz * 2.0 - 1.0); 
    vec3 L = normalize(attrib_Fragment_Light); 
    vec3 V = normalize(attrib_Fragment_Eye); 
    vec3 R = normalize(-reflect(L, N)); 

    // Compute products. 
    float NdotL = max(0.0, dot(N, L)); 
    float RdotV = max(0.0, dot(R, V)); 

    // Compute final colours. 
    vec4 ambient = Light_Ambient_Colour * Material_Ambient_Colour; 
    vec4 diffuse = Light_Diffuse_Colour * Material_Diffuse_Colour * NdotL; 
    vec4 specular = Light_Specular_Colour * Material_Specular_Colour * (pow(RdotV, Material_Shininess) * Material_Strength); 

    // Final colour. 
    Out_Colour = ambient + diffuse + specular;  
} 

编辑:3D Studio的渲染场景的(以显示UV的是OK的球):

enter image description here

我认为你的着色器没问题,但你的球体上的纹理坐标是完全关闭的。就好像它们沿着经度向两极扭曲。

+0

谢谢。我添加了场景的3D Studio渲染,以显示球体上的UV都是OK。它也使用相同的地图进行碰撞。 – Robinson 2012-04-05 16:39:18

+1

像往常一样,你给我一个关于答案datenwolf的好消息。使用color =(u,v,0,1)渲染球体时,它绝对不会在导入该网格时正确处理UV,或者我的着色器未被正确绑定。 – Robinson 2012-04-05 16:53:10

+1

就是这样。顶点着色器需要:\t vary_TextureCoord = attrib_Texture ;.这样一个愚蠢的错误和准备问题的时间:-)。 – Robinson 2012-04-05 16:57:06