2012-04-05 8 views
9

Tanjant alanımdan normal haritalama shader :) 'dan oldukça garip sonuçlar alıyorum. Burada gösterdiğim sahnede, çaydanlık ve damalı duvarlar sıradan Phong-Blinn shader'ımla gölgeleniyor (açıkça çaydanlık arka yüz cull hafif bir geçici bir görünüm veriyor ve :-)). Ben psychedelic sonuçlarla, küre normal haritalama eklemek denedim:Tanjant Uzay Normal Haritalama - shader aklı kontrolü

Incorrect Normal Mapping on Sphere

ışık sağdan geliyor (sadece siyah bir damla gibi görünen hakkında). Ben küre üzerinde kullanıyorum normal harita şuna benzer: Ben girdi modelleri işlemek için AssImp kullanıyorum, bu yüzden benim için otomatik olarak her köşe için teğet ve iki normaller hesaplarken oluyor

Normal Map

.

Piksel ve köşe gölgelendiricileri aşağıdadır. Neyin yanlış gittiğinden emin değilim, ama eğer teğet temel matrisi bir şekilde yanlış olursa beni şaşırtmayacaktı. Bir şeyleri göz alanı içine hesaplamalıyım ve sonra göz ve ışık vektörlerini teğet uzaya dönüştürmeliyim ve bunun bunun için doğru yol olduğunu düşünüyorum. Işık konumunun, görüntü alanında zaten gölgelendiriciye geldiğini unutmayın.

// 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;  
} 

Düzenleme:: 3D Studio sahnenin Render (UV en küre üzerinde Tamam göstermek için):

enter image description here

// 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; 
} 

... ve pixel shader şöyle

cevap

3

Gölgelerinizin iyi olduğunu düşünüyorum, ancak dokudaki koordinatlarınız tamamen kapalı. Boylam boyunca kutuplara doğru çarpmışlar gibi.

+0

Teşekkürler. 3D Studio'yu kürenin üzerindeki UV'lerin tamam olduğunu göstermek için sahneye ekledim. Aynı haritayı da çarpmak için kullanıyor. – Robinson

+1

Her zamanki gibi, bana datenwolf cevabı hakkında iyi bir ipucu veriyorsun. Rengi = (u, v, 0, 1) ile küreye dönüştürmek kesinlikle bu ağ için UV'leri doğru bir şekilde işlemez veya gölgeleyicim doğru şekilde bağlanamaz. – Robinson

+1

Yani öyleydi. Vertex shader gerekli: \t varying_TextureCoord = attrib_Texture ;. Böyle aptal bir hata ve soruyu hazırlarken harcanan zaman :-). – Robinson