2013-08-27 85 views
1

所以,我在世界空間有一個光線方向,並且我計算了每個頂點的法線......但是我對我的法線貼圖實現有點困惑。現在我正在這樣做。法線貼圖實現....我在這裏錯過了什麼嗎?

// Normal Map 
const float3 normalmap = (2.0f*gTextures1024.Sample(gLinearSam, float3(_in.Tex, gNormalMapIndex)).rgb) - 1.0f; 
const float3 NormalW = _in.Norm; 
const float3 TangentW = normalize(_in.TangentW.xyz - dot(_in.TangentW.xyz, _in.Norm)* _in.Norm); 
const float3 BitangentW = cross(NormalW, TangentW) * _in.TangentW.w; 

const float3x3 TBN = float3x3(TangentW, BitangentW, NormalW); 

float3 normal = normalize(mul(TBN, normalmap)); 
// Lighting Calculations 
//float4 normal = normalize(float4(_in.Norm, 0.0f)); 
float3 hvector = normalize(mul(-gDirLight.Direction.xyz, TBN) + gEyePos).xyz; 
//hvector = mul(hvector.xyz, TBN); 
float4 ambient = gDirLight.Ambient * gMaterial.Ambient; 
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f); 
float4 specular = float4(0.0f, 0.0f, 0.0f, 0.0f); 
float4 texColor = float4(1.0f, 1.0f, 1.0f, 1.0f); 

[branch] 
if(gUseTextures) 
    texColor = gTextures1024.Sample(gLinearSam, float3(_in.Tex, gDiffuseMapIndex)); 

// diffuse factor 
float diffuseFactor = saturate(dot(normal, -gDirLight.Direction.xyz)); 
[branch] 
if(diffuseFactor > 0.0f) 
{ 
    diffuse = diffuseFactor * gDirLight.Diffuse * gMaterial.Diffuse; 
    // Specular facttor & color 
    float HdotN = saturate(dot(hvector, normal)); 
    specular = gDirLight.Specular * pow(HdotN, gMaterial.Specular.w); 
} 

// Modulate with late add 
return (texColor * (ambient + diffuse)) + specular; 

我在這裏做錯了什麼?據我說,我正在世界空間實施法線貼圖計算,一切都應該正常運行......我在這裏錯過了什麼嗎?

回答

2

TBN是一種將矢量從世界空間轉換爲切空間的矩陣。因此,您應該在切線空間中進行照明計算。

從法線貼圖獲取的法線已經在切線空間(假定)。因此,您需要將光線方向和眼睛位置轉換爲切線空間,並照常繼續計算。

0

尼科,你是對的。但是,我遇到了很多問題,這些問題正在我身上蔓延。

問題#1:我沒有正確計算我的法線。我使用的是每個頂點的平均值,但甚至沒有意識到有加權平均這樣的技術。這是我的所有照明改善了2000%。

問題2:切線和平切線計算也沒有正確完成。我可能還會在這方面做出改進,看看我是否也可以對它們進行加權平均。

問題3:我沒有正確地進行照明計算,在維基百科進行了大約2天后,我終於做到了正確,並且現在完全清楚地理解了它。

問題4:我只是想快點做,而不理解100%我在做什麼(從不再犯這個錯誤)。

相關問題