像素級高光效果計算(一)

來源:http://www.sunnycrystal.net/showdocs.aspx?id=20

產生高光效果的基本算法是:

一、計算得到像素到眼睛的射線單位向量,該單位向量等於眼睛位置減去象素的位置,然後歸1化:EyeVec = Normalize( EyePosition - Position ));另外,有一種簡化模式效果也不錯,偶就是採用這種模式:假設眼睛在無限遠,則EyeVec爲常量,所以,EyeVec = Normalize( EyePosition - 物體Position ),在這種模式下,無需在VS中對物體進行Per-Vertex的EyeVec計算。


二、計算Halfway Vector(中間向量、中途向量),HalfwayVec = Normalize( EyeVec + LightVec ),其中LightVec的方向是從光照處指向燈光,該向量表示了在當前眼睛所在位置,該像素若發生高光全反射時的法向量(即HalfwayVec)

三、將HalfwayVec與實際的像素法向量比較得到當前像素反光度,越與HalfwayVec接近,反光越強烈,所以可以利用點乘來達到這一目的,反光度 = HalfwayVec 點乘 Normal。

四、調整光亮度,可以將反光度進行N次方運算,以縮小光斑,得到不同材質的效果

五、將物體Diffuse顏色加上( 反光度, 反光度, 反光度 )的顏色。Diffuse.r += 反光度;Diffuse.g += 反光度;Diffuse.b += 反光度;

高光效果1:

像素高光算法的精度問題

該算法的缺點就是數據精度問題,其關鍵是法線歸1化時的精度問題,如果採用CubeMap方式歸一化法線,則由於第四步的多次乘方造成了高光區落在了一個很小的區間裏,將出現高光離散的塊狀現象,下圖用平滑化的表面展示了這一問題:

爲了避免這一問題的產生,我們可以採用一種N Dot H / H Dot H的算法( PS.2.0及以上可以採用Normalize()直接解決這一問題 ):

可以建立一塊N Dot H / H Dot H紋理,把N Dot H值作爲U座標,把H Dot H值作爲V座標,紋理顏色R = Pow( N Dot H / sqrt( H Dot H ), 鏡面指數K ),然後PS就將歸一化省去,直接用N Dot H和H Dot H作爲紋理座標查找這塊紋理,直接將歸一化和指數化合二爲一。渲染結果將不再出現色斑,效果如下:

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