2012-02-19 28 views
2

我在我的OpenGL遊戲引擎中有一個正常貼圖,並且我意識到我的正常貼圖着色器(和視差貼圖着色器)對光照有問題。無論光線在哪裏,光線總是來自右邊。我正在使用切線空間着色器,而且我不確定我傳遞的是否正確。正常貼圖中的光照不正確

這是正常的地圖,我現在用: The Normal Map I am using

這裏是渲染:

Rendered Image

的光似乎從座標3,0,3來,但其實際位置是-3,0,3

任何想法。

着色器:

[VERT]

attribute vec3 intan; 

varying vec3 lightDir; 
varying vec3 viewDir; 

void main() 
{ 
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
gl_TexCoord[0] = gl_MultiTexCoord0; 

vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex); 

vec3 n = normalize(gl_NormalMatrix * gl_Normal); 
vec3 t = normalize(gl_NormalMatrix * intan); 
vec3 b = cross(n, t) ; 

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

lightDir = (gl_LightSource[1].position.xyz - vertexPos)/1000.; 
lightDir = tbnMatrix * lightDir; 

viewDir = -vertexPos; 
    //viewDir = 
viewDir = tbnMatrix * viewDir; 
} 

[FRAG]

uniform sampler2D tex; 
uniform sampler2D nor; 

varying vec3 lightDir; 
varying vec3 viewDir; 

const vec4 d = vec4(0.19225,0.19225,0.19225,1.0); 
const vec4 a = vec4(0.50754,0.50754,0.50754,1.0); 
const vec4 s = vec4(0.508273,0.508273,0.508273,1.0); 

void main() 
{ 
vec3 l = lightDir; 
float atten = max(0.0, 1.0 - dot(l, l)); 

l = normalize(l); 

vec3 n = normalize(texture2D(nor, gl_TexCoord[0].st).xyz * 2.0 - 1.0); 
vec3 v = normalize(viewDir); 
vec3 h = normalize(l + v); 

float nDotL = max(0.0, dot(n, l)); 
float nDotH = max(0.0, dot(n, h)); 
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess); 

vec4 ambient = a * atten; 
vec4 diffuse = d * nDotL * atten; 
vec4 specular = s * power * atten; 
vec4 color = ambient + diffuse + specular; 

gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st); 
} 
+0

對於酷地圖+1。但任何想法?爲什麼不只是破解vertexPos.x = -vertexPos.x – 2012-02-19 01:22:29

+0

我嘗試過,但是我會因爲另一邊的光線而出現問題。 – 2012-02-19 02:31:27

回答

0
vec3 n = normalize(gl_NormalMatrix * gl_Normal); 
vec3 t = normalize(gl_NormalMatrix * intan); 
vec3 b = cross(n, t) ; 

我想intan指定方向,其中,法線圖「右「p oints。然後那個交叉產品是錯誤的。如果n指向表面並向右移動,則b(正常)指向下。

請注意,如果您轉換法線和切線,然後執行結果的交叉乘積或先交叉乘積並轉換結果,則不會有任何區別。

lightDir =(gl_LightSource [1] .position.xyz - vertexPos)/ 1000 .;

爲什麼你不正常呢? 1000除法是沒有意義的。

+0

除以1000是我如何計算衰減。如果你在我的片段着色器中查看,我將矢量長度減去1,然後得到0.0和0.0之間的最大值。 1000表示我的光線可以達到1000個光照單位。我無法深入解釋。我只知道它的工作原理 – 2012-02-19 01:58:41