2013-03-10 238 views
6

我只是想知道我的理解TBN矩陣計算正確法線貼圖,TBN矩陣計算

在頂點着色器,我們通常使用:

vec3 n = normalize(gl_NormalMatrix * gl_Normal); 
vec3 t = normalize(gl_NormalMatrix * Tangent.xyz); 
vec3 b = normalize(gl_NormalMatrix * Bitangent.xyz); 
mat3 tbn = mat3(t, b, n); 

據我瞭解這個tbn矩陣從變換的矢量Tangent space to Eye space。實際上,我們想要反轉 - 從眼睛空間向Tangent空間轉換矢量。因此,我們需要反轉tbn矩陣:

tbn = transpose(tbn); // transpose should be OK here for doing matrix inversion 

注:tbn - 應該只包含旋轉,對於這種情況下,我們可以使用轉逆矩陣。

我們可以改變我們的載體:

vec3 lightT = tbn * light_vector; 
...   = tbn * ... 

在幾個教程,源代碼中我發現,作者用這樣的:

light.x = dot(light, t); 
light.y = dot(light, b); 
light.z = dot(light, n); 

上面的代碼不一樣乘以由transposed(tbn)矩陣組成。

問題:

我們應該用換位tbn矩陣正如我上面所解釋的?或者我錯過了什麼?

註解通過該解決方案,我們將矢量(light_vector)轉換爲頂點着色器中的TBN,然後在片段着色器中我們只需從法線貼圖中獲得法線。其他選項是創建從TBN空間轉換到眼圖空間的TBN矩陣,然後在片段着色器中從法線貼圖轉換每個讀取法線。

+0

定義「正確的「?你把你的正常和切向量的交叉乘積拿到你的苦味矢量。一般來說,這對於大多數表面來說*不是正確的。對你來說這可能是正確的,但大多數紋理映射不使用完美的正交映射到曲面。 – 2013-03-10 21:54:08

+0

對,我已經更新了這個問題。我也改變了不安的計算方式。 – fen 2013-03-11 08:01:47

回答

0

轉置不是矩陣的倒置!!!

在頂點着色器我的TBN矩陣是這樣的:

uniform mat4x4 tm_l2g_dir; 
layout(location=3) in vec3 tan; 
layout(location=4) in vec3 bin; 
layout(location=5) in vec3 nor; 
out smooth mat3 pixel_TBN; 

void main() 
{ 
    vec4 p; 
    //... 
    p.xyz=tan.xyz; p.w=1.0; pixel_TBN[0]=normalize((tm_l2g_dir*p).xyz); 
    p.xyz=bin.xyz; p.w=1.0; pixel_TBN[1]=normalize((tm_l2g_dir*p).xyz); 
    p.xyz=nor.xyz; p.w=1.0; pixel_TBN[2]=normalize((tm_l2g_dir*p).xyz); 
    //... 
} 

其中:

  • tm_l2g_dir是從局部模型空間,以世界舞臺的空間變換矩陣whitout任何運動(改變只向)你的代碼它是你的正常矩陣
  • tan,bin,TBN矩陣的矢量(作爲我的模型的一部分)

也不 - 是法線矢量從實際頂點位置到表面(可以計算從該頂點的兩個頂點的矢量乘法)

棕褐色,箱是垂直載體通常平行於紋理映射軸系或模型的teselation。如果選擇錯誤的tan/bin向量,則有時會出現一些照明僞影。例如,如果你有氣缸比倉是其旋轉軸和黃褐色是垂直於它沿着圓(正切)

棕褐色,bin中,也不應垂直於彼此

就可以計算出TBN也自動但這會導致一些文物。要做到這一點,你只需選擇用於正常的計算和斌=也不X斌爲棕褐色矢量一個頂點

在片段着色器

我使用pixel_TBN與法線貼圖來計算真​​正的正常片段

//------------------------------------------------------------------ 
#version 420 core 
//------------------------------------------------------------------ 
in smooth vec2 pixel_txr; 
in smooth mat3 pixel_TBN; 
uniform sampler2D txr_normal; 
out layout(location=0) vec4 frag_col; 
const vec4 v05=vec4(0.5,0.5,0.5,0.5); 
//------------------------------------------------------------------ 
void main(void) 
    { 
    vec4 col; 
    vec3 normal; 
    col=(texture2D(txr_normal,pixel_txr.st)-v05)*2.0;  // normal/bump maping 
    normal=pixel_TBN*col.xyz; 
    // col=... other stuff to compute col 

    frag_col=col; 
    } 
//------------------------------------------------------------------ 
+1

你在片段着色器中如何處理pixel_TBN?據我所知,您可以將tan,bin或Tangent Space轉換爲全局場景空間。對於只包含旋轉的矩陣,可以使用轉置進行反演。 – fen 2013-08-07 07:09:36

+0

只是爲你編輯了簡單的部分片段。在每個片段正常情況下,您可以執行任何操作(任何照明模型,從立方體貼圖添加鉻反射...) – Spektre 2013-08-08 22:25:37

+2

正常3x3的轉置也是相反的。也許這就是原來的海報所指的? – Tommy 2013-08-08 22:43:11