原文地址: http://www.bennychen.cn/2009/07/%E9%A1%B6%E7%82%B9%E6%B3%95%E7%BA%BF/
本來以為前一段時(shí)間寫的3d max導(dǎo)出插件已經(jīng)沒有什么大的問題了,但有沒有問題,完善不完善,真不是憑感覺就OK的,必須有足夠廣泛的測試用例測試后,才能夠證明。
這不,最近開始研究并寫一些光線跟蹤的例子了,這當(dāng)然離不開模型的法線,于是在進(jìn)行當(dāng)中我就發(fā)現(xiàn),我的導(dǎo)出插件所導(dǎo)出的法線是不完善的。
在原來的插件中,我讓頂點(diǎn)的法線就直接等于其所在的三角形面的 面法線 (多個(gè)面共享1個(gè)頂點(diǎn),則會(huì)導(dǎo)出多個(gè)頂點(diǎn),這些頂點(diǎn)位置相同法線不同),但對于光照模型,面法線只能支持到Lambert,為了支持Gouraud, Phong等其他模型,則必須使用 頂點(diǎn)法線 (為什么?稍后解釋)。
這里提出了頂點(diǎn)法線和面法線,首先需要清楚的理解并區(qū)分這兩個(gè)概念。
面法線很容易理解,即垂直于三角形面的一條法線。那頂點(diǎn)法線又從何而來呢,嚴(yán)格的從法線的定義上來說,其實(shí)頂點(diǎn)是不存在法線的,那為何又有頂點(diǎn)法線這個(gè)概念的。讓頂點(diǎn)也擁有法線,是為了在光照計(jì)算時(shí),能夠在多面體的表面獲得一種平滑的效果。
更具體的說,如果不使用頂點(diǎn)法線(就像我的3dmax導(dǎo)出插件原來就直接讓頂點(diǎn)法線等于其面法線一樣),一個(gè)三角形面的三個(gè)頂點(diǎn)的光照計(jì)算按照其所在面的面法線來計(jì)算,因?yàn)槿齻€(gè)頂點(diǎn)的法線相同,則與光照方向求點(diǎn)積之后的結(jié)果也相同,這樣三個(gè)頂點(diǎn)將會(huì)獲得相同的光照效果,之后,光柵化再怎么插值,整個(gè)表面也都只是一種光禿禿的效果。(如圖1)
而如果使用頂點(diǎn)法線,同一個(gè)面的三個(gè)頂點(diǎn)的法線就不一定相同了,這樣通過光柵化后,就能在多面體的表面獲得一種平滑過渡的光照效果。(如圖2)
于是,弄清楚了這個(gè)后,我需要再次修改我的3dmax導(dǎo)出插件了,需要計(jì)算并生成新的頂點(diǎn)法線。那頂點(diǎn)法線該如何計(jì)算呢,對于這個(gè)我在這里就不詳述,Max Wagner的《Generating Vertex Normals》這篇文章說的很詳細(xì)清楚,從最簡單的到逐步優(yōu)化的生成算法一一都有介紹,可以去google找一下。
而3dmax的SDK開發(fā)文檔里對頂點(diǎn)法線的計(jì)算也有介紹,3dmax提供了一個(gè)smoothing group的概念,這對于像立方體盒子這種表面并不是平滑過渡的模型,計(jì)算它們的法線將會(huì)帶來很大的幫助。Wagner的文章里也說了,對于像立方體這樣的模型,頂點(diǎn)法線不能簡單的等于(共享該頂點(diǎn)的面的)面法線的平均值,因?yàn)檫@些面之間的過渡并不平滑。按照3dmax的概念,這些面不屬于同一個(gè)smoothing group。何為smoothing group,這是3dmax根據(jù)表面之間的平滑過度情況,進(jìn)行的分組。比如立方體,因?yàn)?個(gè)面之間兩兩都是相互不平滑的,所以一共會(huì)有6個(gè)smoothing group。每個(gè)面所屬的平滑組的ID,程序員是可以直接讀出的。
下面這兩張圖,是我在修改前和修改后的光照效果,對比很明顯。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
