2012-04-05 9 views
9

私の接線空間のノーマルマッピングシェイダーからかなり奇妙な結果が得られます:)。私がここに示しているシーンでは、ティーポットとチェッカーされた壁は私の普通のPhong-Blinnシェーダで覆われています(明らかにティーポットのバックカーカルは軽く儚いものです:-))。接線空間ノーマルマッピング - シェーダの健全性チェック

Incorrect Normal Mapping on Sphere

光が(黒色ブロブとしてちょうど約可視)右から来ている:私はサイケデリック結果と、球体の法線マッピングに追加する試みました。私は球に使っている法線マップは以下のようになります。私は、入力モデルを処理するためにAssImpを使用しているので、それが私のために自動的に各頂点に対して接線と双方向法線を計算しています

Normal Map

ピクセルシェーダと頂点シェーダは以下のとおりです。私は何がうまくいかないのかはっきりしていませんが、接線基底行列が何らかの形で間違っていると私には驚かないでしょう。私は、目の空間に物を計算し、次に目と光のベクトルを接線の空間に変換しなければならないと仮定し、これが正しい方法です。ライトの位置は既にビュー空間内のシェーダに入っていることに注意してください。

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

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

...とピクセルシェーダはこのようになります

答えて

3

あなたのシェーダは大丈夫だと思いますが、球面のテクスチャ座標は完全に消えています。経度に沿って極に向かってゆがんでいるかのようです。

+0

ありがとうございました。私は球のUVがすべてOKであることを示すシーンの3Dスタジオレンダリングを追加しました。同じマップをバンプに使用しています。 – Robinson

+1

いつものように、私は答えdatenwolfについての良い手がかりを与えます。球体をcolor =(u、v、0、1)でレンダリングすると、このメッシュのインポート時にUVを正しく処理していないか、シェーダーが正しくバインドされていません。 – Robinson

+1

そうだった。頂点シェーダが必要:\t varying_TextureCoord = attrib_Texture ;.そのような愚かな間違いと時間を質問の準備に費やした:-)。 – Robinson