書接上回,說完了繪製(其實繪製說的很簡略,有空再補上吧),現在就該聊一聊光照了。
因為光照比前面的繪製有趣些,所以就多說幾句吧。:)
在D3D中(當然,OpenGL也如此),光被分成三種類型:
環境光線(Ambient),漫射光(Diffuse),鏡面光(Specular),這三種光可以同時混合使用,也可使用其中某一種或幾種光。值得注意的是,鏡面光在預設情況下是不會被D3D計算的,只有你將相應的繪製狀態設定為true之後,才會做鏡面光計算 device->SetRenderState(D3DRS_SPECULARENABLE, true) 。之所以在預設情況下,鏡面光是關閉的,因為這種光涉及的計算量相當龐大,不太適合於即時渲染,所以通常是關閉的。
環境光線:顧名思義,就是在環境中的光線,它是一個平行光(就像太陽光),來自某個方向,射向物體表面,形成明暗差別。這種方式的計算量較小,但擬真度不高,所以在低擬真度高即時性限制下,可以湊合著用。
漫射光:這種光來自某個光源,然後到達物體表面後,被均勻的漫反射開,所以,這就導致不管觀察者從哪個角度看,物體所反射的亮度都差不多。也正是這個特性,幫我們大大簡化了漫反射計算方程。當然,要注意的是,因為漫反射會均勻反射光線,所以,這種光用多了之後,會導致物體的立體感降低。
鏡面光:顯然,這種光的特性就是像鏡子一樣,將光按照規定的法線反射出去。比如,有些物體在某一點上會特別的亮,這就是鏡面光使然。
上面說到的3種光,其實都是需要作用在物體表面才能被大家感知的。不同的物體表面特性,就會產生不同強度的 環境光線分量,漫射光分量和鏡面光分量(如果開啟鏡面光的話)。描述這種表面特性的參數 就叫 材質(material)。
D3D對 material定義如下:
typedef struct D3DMATERIAL9{
D3DCOLORVALUE Diffuse;
D3DCOLORVALUE Ambient;
D3DCOLORVALUE Specular;
D3DCOLORVALUE Emissive;
float Power;
} D3DMATERIAL9
大家可以發現,一個材質變數,包含了環境光線、漫反射、鏡面光這3個分量的反射強度描述。採用COLOR表示,也就是說,可以分別描述三個光分量對 R、G、B的反射特性。D3D會根據這些值來分別計算反射出來的光的強度和顏色。
除了3個光分量外,還有一個Emissive量,這個量描述了物體的自發光強度,就是說如果物體本身在發光,那麼,就可以對Emissive進行設定,分別設定R、G、B強度。
最後一個成員,Power,它定義了高光點的銳度,值越大,銳度越大。
例子:
比如,我們想要一個物體,它只漫反射紅光,鏡面反射綠光,反射的環境光線為藍色,就可以設定為:
D3DMATERIAL9 color_obj;
color_obj.Diffuse = D3DXCOLOR(0.5, 0.0f, 0.0f, 0.0f); //RGBA
color_obj.Ambient = D3DXCOLOR(0.0f, 0.0f, 1.0f, 0.0f);
color_obj.Specular = D3DXCOLOR(0.0f, 1.0f, 0.0f, 0.0f);
上面就描述了一個材質,漫反射光只反射50%的紅色,而藍色和綠色被完全吸收(就是不反射);環境反射光對綠色100%反射,對紅色和藍色完全吸收......以此類推。
因此,當我們用藍色光源照射只反射紅色光的材質時,該物體將會是黑色,因為藍色被完全吸收了。
To be continued...