normalMap的七七八八

2021-09-08 07:44:39 字數 1885 閱讀 5399

關於normalmap,主要是要談談tangent space,可以自行生成,或者從3dmax裡取。

我是這樣想的,當檢查到mesh的material使用了normalmap,那麼mesh就會匯出tangent和binormal。

通過2天不停得試驗和翻閱文件,有幾點認知是需要明確指出:

1.  tangent變換並不是正交變換,大部分情況下頂點normal和三角形表面是不垂直的,tangent和binormal也未互相必垂直。不考慮映象對映的話還只是誤差,映象對映之後乾脆連方向都反了。

2.  如上述,一般的說法,在vertex buffer中只存tangent,而在vertex shader中使用cross(tangent, normal)計算出binormal是不正確的。

3.  美術可能只畫半張臉的normalmap,而另一半使用mirror出來。這種情況,使用cross出binormal的效果,就會原本凹的凸,凸的變凹。

4.  還有一種說法,是重新計算比如tangent在平面上的投影,也就是gram-schmidt orthogonalize,但我的結論是在max中不需要這麼做。

5.  直接取max給的tangent和binormal是絕對不行的,那會變成這樣,見下圖: 

左邊是ogre自動生成的tangent,右邊是直接取max的tangent不作處理,兩者的binormal都是cross出來的,兩者中間的映象都是不正確的。

結論是:

1.  必須是源生tangent, binormal,指望只存1個,用cross出來另乙個是想法是錯誤的。

2.  要處理映象,不單是tangent,連binormal都可能反向。

關鍵**如下:

if(hastangent)

{int

tangentindex 

=mesh

->

getfacevertextangentbinormal(face

->

meshfaceindex, vertexidx, tangentchannel);

vertex.tangent 

=mesh

->

gettangent(tangentindex, tangentchannel);

vertex.binormal 

=mesh

->

getbinormal(tangentindex, tangentchannel);

if(vertex.binormal 

%crossprod(vertex.normal, vertex.tangent) 

<0)

vertex.tangent *=-

1.0f;if

(vertex.tangent 

%crossprod(vertex.normal, vertex.binormal) 

<0)

vertex.binormal *=-

1.0f;

這是處理後的ndotl圖:

注意這個地方:

如果不處理則會凹凸相反。

最終的渲染效果:

normalMap的七七八八

關於normalmap,主要是要談談tangent space,可以自行生成,或者從3dmax裡取。我是這樣想的,當檢查到mesh的material使用了normalmap,那麼mesh就會匯出tangent和binormal。通過2天不停得試驗和翻閱文件,有幾點認知是需要明確指出 1.tangen...

記錄各個七七八八的輸入 持續更新中

注 當輸入回車 空格 tab鍵的時候,程式不會退出 int main number return 0 include include includeusing namespace std int main void while shuzi system pause return 0 輸入 1 2 c...

Oracle學習筆記 字串的七七八八

oracle有兩種字串型別 char 和varchar2 其實還有varchar,但也許oracle在今後會有一些變化,所以為了安全起見,還是使用varchar2 其中char是定長的,如果設定了小於char長度的字串,oracle會用空格填充為等長的串,而且在比較char時,也會有空格填充的問題,...