頂點法線

原文地址:http://www.bennychen.cn/2009/07/%E9%A1%B6%E7%82%B9%E6%B3%95%E7%BA%BF/

本來以爲前一段時間寫的3d max導出插件已經沒有什麼大的問題了,但有沒有問題,完善不完善,真不是憑感覺就OK的,必須有足夠廣泛的測試用例測試後,才能夠證明。

這不,最近開始研究並寫一些光線跟蹤的例子了,這當然離不開模型的法線,於是在進行當中我就發現,我的導出插件所導出的法線是不完善的。

在原來的插件中,我讓頂點的法線就直接等於其所在的三角形面的面法線(多個面共享1個頂點,則會導出多個頂點,這些頂點位置相同法線不同),但對於光照模型,面法線只能支持到Lambert,爲了支持Gouraud, Phong等其他模型,則必須使用頂點法線(爲什麼?稍後解釋)。

這裏提出了頂點法線和麪法線,首先需要清楚的理解並區分這兩個概念。

面法線很容易理解,即垂直於三角形面的一條法線。那頂點法線又從何而來呢,嚴格的從法線的定義上來說,其實頂點是不存在法線的,那爲何又有頂點法線這個概念的。讓頂點也擁有法線,是爲了在光照計算時,能夠在多面體的表面獲得一種平滑的效果。

更具體的說,如果不使用頂點法線(就像我的3dmax導出插件原來就直接讓頂點法線等於其面法線一樣),一個三角形面的三個頂點的光照計算按照其所在面的面法線來計算,因爲三個頂點的法線相同,則與光照方向求點積之後的結果也相同,這樣三個頂點將會獲得相同的光照效果,之後,光柵化再怎麼插值,整個表面也都只是一種光禿禿的效果。(如圖1)

而如果使用頂點法線,同一個面的三個頂點的法線就不一定相同了,這樣通過光柵化後,就能在多面體的表面獲得一種平滑過渡的光照效果。(如圖2)

於是,弄清楚了這個後,我需要再次修改我的3dmax導出插件了,需要計算並生成新的頂點法線。那頂點法線該如何計算呢,對於這個我在這裏就不詳述,Max Wagner的《Generating Vertex Normals》這篇文章說的很詳細清楚,從最簡單的到逐步優化的生成算法一一都有介紹,可以去google找一下。

而3dmax的SDK開發文檔裏對頂點法線的計算也有介紹,3dmax提供了一個smoothing group的概念,這對於像立方體盒子這種表面並不是平滑過渡的模型,計算它們的法線將會帶來很大的幫助。Wagner的文章裏也說了,對於像立方體這樣的模型,頂點法線不能簡單的等於(共享該頂點的面的)面法線的平均值,因爲這些面之間的過渡並不平滑。按照3dmax的概念,這些面不屬於同一個smoothing group。何爲smoothing group,這是3dmax根據表面之間的平滑過度情況,進行的分組。比如立方體,因爲6個面之間兩兩都是相互不平滑的,所以一共會有6個smoothing group。每個面所屬的平滑組的ID,程序員是可以直接讀出的。

下面這兩張圖,是我在修改前和修改後的光照效果,對比很明顯。

lambert圖1:基於面法線的光照

gouraud圖2:基於頂點法線的光照


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章