2013-03-10 77 views
4

我是按照正常映射許多在線教程,並且已經得到了它的工作,在一定程度上......我似乎法線貼圖問題

不能讓它正常工作,除非多邊形是垂直於視圖矢量。

我已經創建了一個視頻來說明這一點,因爲圖片並不足以展示我的意思。

http://www.youtube.com/watch?v=9D4o_zy-61s

我已經發布我的着色器:

頂點:

#version 400 
layout (location = 0) in vec3 attribPosition; 
layout (location = 1) in vec3 attribNormal; 
layout (location = 2) in vec2 attribTexCoord; 
layout (location = 3) in vec3 attribTangent; 
layout (location = 3) in vec3 attribBinormal; 

uniform mat4 mvp; 
uniform mat4 mvm; 
uniform mat3 nm; 
uniform vec3 lightPos_World; 

out vec2 vUvs; 
out vec3 lightPos_Eye; 
out vec3 vertexPos_Eye; 
out vec3 normalDir_Eye; 
out vec3 normalDir_World; 
out mat3 tbnMatrix; 

void main() 
{ 
    vUvs = attribTexCoord; 
    normalDir_World = attribNormal; 
    normalDir_Eye = (nm * attribNormal); 
    vec3 t = nm * attribTangent; 
    vec3 n = nm * attribNormal; 
    vec3 b = nm * cross(n,t); 

    mat3 tbnMatrix = mat3(t.x, b.x, n.x, 
          t.y, b.y, n.y, 
          t.z, b.z, n.z); 

    vertexPos_Eye = (mvm * vec4(attribPosition,1.0)).xyz; 
    lightPos_Eye = (mvm * vec4(lightPos_World,1.0)).xyz; 

    gl_Position = mvp * vec4(attribPosition,1.0); 
} 

片段:

#version 400 
layout(location = 0) out vec4 frag_main; 
struct PointLight{ 
    vec3 position; 
    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
    float shininess; 
    float intensity; 
}; 

uniform PointLight light[2]; 
uniform sampler2D colorTexture; 
uniform sampler2D normalTexture; 
uniform mat4 mvm; 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
// FLAGS - all flags start false; 
// [0][0] = colour map 
// [0][1] = normal map 
// [0][2] = unused 
// [0][3] = show normal map in colour channel 
// [1][0] = use tangent space 
// [1][1] = unused 
// [1][2] = unused 
// [1][3] = unused 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
uniform bvec4 flags[2]; 

in vec3 vertexPos_Eye; 
in vec3 normalDir_World; 
in vec3 normalDir_Eye; 
in vec2 vUvs; 
in mat3 tbnMatrix; 


void main(){ 

    uint numLights=2; 

    vec3 colorFragment; 
    if(flags[0][0]){ 
     colorFragment = texture(colorTexture,vUvs).xyz; 
    }else{ 
     colorFragment = vec3(0.5); 
    } 

    vec3 normalMapNormal = (texture(normalTexture,vUvs).rgb * 2) - 1; 
    vec3 normalDir; 
    if(flags[0][1]){ 
     normalDir = normalize(normalDir_Eye); 
    }else{ 
     normalDir = normalize(normalMapNormal.rgb); 
    } 

    vec4 outColor = vec4(1); 
    outColor.xyz = vec3(0); 

    float duller = 1/numLights; 
    for(int i = 0;i< numLights;i++){ 
     vec3 lightPos_Eye = (mvm * vec4(light[i].position,1.0)).xyz; 
     vec3 lightDir_Eye = normalize(lightPos_Eye - vertexPos_Eye); 
     vec3 lightDir_Tangent = lightDir_Eye * tbnMatrix; 

     vec3 vertDir_Eye = normalize(-vertexPos_Eye); 
     vec3 vertDir_Tangent = vertDir_Eye * tbnMatrix; 

     vec3 halfDir_Eye = normalize(vertDir_Eye + lightDir_Eye); 
     vec3 halfDir_Tangent = halfDir_Eye * tbnMatrix; 

     vec3 Ia = colorFragment.xyz * light[i].ambient; 
     vec3 Id; 
     vec3 Is; 

     // tangent space 
     Id = (colorFragment.xyz * light[i].diffuse) * max(dot(lightDir_Tangent, normalDir), 0); 
     Is = light[i].specular * pow(max(dot(halfDir_Eye, normalDir), 0), light[i].shininess*2); 
     // eye space 
     //Id = (colorFragment.xyz * light[i].diffuse) * max(dot(lightDir_Eye, normalDir), 0); 
     //Is = light[i].specular * pow(max(dot(halfDir_Eye, normalDir), 0), light[i].shininess*2); 

     outColor.xyz += (Ia + Id + Is); 

    } 

    if(flags[0][3]){ 
     outColor.xyz = normalDir; 
    } 
    frag_main = (outColor); 
} 
+0

對於視頻演示+1。 – 2013-03-10 08:03:26

回答

0

我注意到行:

vec3 b = nm * cross(n,t); 

,但它應該是:

vec3 b = cross(n,t); 

沒有必要通過nm再次倍增,因爲nt在所需的攝像機空間。

另一件事:

lightPos_Eye = (mvm * vec4(lightPos_World,1.0)).xyz; 

由於lightPos_World是世界空間(如名字所暗示的),你應該像* world_matrix *通過模型視圖相乘,不是。或者只需在應用程序代碼中計算lightPos_Eye並將其發送到頂點着色器。

很難管理所有這些不同的載體,並將它們放在一個合適的空間中。有時候,視覺錯誤是非常微妙的,很難發現。

+0

感謝您的快速響應!不幸的是,在我做出這樣的改變後它仍然是一樣的。 – finlaybob 2013-03-10 11:59:43

+0

我添加了一件我注意到的事情 - 可能是錯誤的光線位置計算。希望它有幫助 – fen 2013-03-10 14:10:25

+0

我也試着改變這一點。隨着這種改變,燈光相對於相機保持不變,並且將其乘以模型視圖矩陣(我只從相機旋轉中獲取)是一種修復,以使燈光相對於相機移動保持「靜止」。 它不能解決需要垂直於多邊形的問題,但不幸的是。 雖然我沒有想過嘗試,所以謝謝! – finlaybob 2013-03-10 14:46:05