2012-04-05 37 views
9

我從我的切線空間法線貼圖着色器得到了一些非常怪異的結果:)。在這裏展示的場景中,茶壺和格子牆被我普通的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

回答

3

我認爲你的着色器沒問題,但你的球體上的紋理座標是完全關閉的。就好像它們沿着經度向兩極扭曲。

+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