像素级高光效果计算(一)

来源: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作为纹理座标查找这块纹理,直接将归一化和指数化合二为一。渲染结果将不再出现色斑,效果如下:

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