反射光源 (Direct3D 9)
模型反射不僅需要系統知道光線的移動方向,還需要知道檢視器眼睛的方向。 系統使用簡化 Phong 鏡面反射模型的版本,運用半程向量來近似計算鏡面反射的強度。
預設光源狀態不計算反射強光。 若要啟用反射光源,請務必將D3DRS_SPECULARENABLE設為 TRUE。
反射光源方程式
反射光源是由下列方程式描述:
反射光源 = Cs * sum[Ls * (N ·H) P * Atten * Spot]
下表會識別變數、其類型和範圍。
參數 | 預設值 | 類型 | Description |
---|---|---|---|
Cₛ | (0,0,0,0) | D3DCOLORVALUE | 反射色彩。 |
Sum | N/A | N/A | 每道光的反射元件的總和。 |
N | N/A | D3DVECTOR | 頂點標準。 |
H | N/A | D3DVECTOR | 半程向量。 請參閱有關半程向量的一節。 |
P | 0.0 | FLOAT | 鏡面反射力。 範圍是 0 到 + 無限大 |
Lₛ | (0,0,0,0) | D3DCOLORVALUE | 淺色反射。 |
Atten | N/A | FLOAT | 光衰減值。 請參閱 衰減和焦點因數 (Direct3D 9) 。 |
付現 | N/A | FLOAT | 聚光燈係數。 請參閱 衰減和焦點因數 (Direct3D 9) 。 |
Cₛ 的值為:
if(SPECULARMATERIALSOURCE == D3DMCS_COLOR1)
C = color1;
- 頂點色彩1,如果反射材質來源D3DMCS_COLOR1,而且頂點宣告中會提供第一個頂點色彩。
- 頂點色彩2,如果反射材質來源D3DMCS_COLOR2,而第二個頂點色彩則會在頂點宣告中提供。
- 材料反射色彩
注意
如果使用任一反射材質來源選項,而且未提供頂點色彩,則會使用材質反射色彩。
所有的光分開處理和插補之後,反射元件會鉗制為從 0 到 255。
半程向量
半程向量 (H) 存在於兩個向量之間路程的一半:從物件頂點到光源的向量,以及從物件頂點到相機位置的向量。 Direct3D 提供兩種方式來計算半程向量。 當D3DRS_LOCALVIEWER設定為 TRUE時,系統會使用相機的位置和頂點的位置,以及光線的方向向量來計算半程向量。 下列公式說明這點。
H = norm (norm (Cp - Vp) + Ldir)
參數 | 預設值 | 類型 | Description |
---|---|---|---|
Cₚ | N/A | D3DVECTOR | 相機位置。 |
Vₚ | N/A | D3DVECTOR | 頂點位置。 |
Ldir | N/A | D3DVECTOR | 從頂點位置至光線位置的方向向量。 |
以這種方式判斷半程向量可能會需要大量運算資源。 或者,設定 D3DRS_LOCALVIEWER = FALSE 會指示系統在 Z 軸上無限遠的視點運作。 其計算公式如下。
H = norm ( (0,0,1) + Ldir)
此設定比較不需要大量運算資源,但比較不精確,因此最適合供使用正交投影的應用程式使用。
範例
在這個範例,物件使用場景反射淺色和材料反射色彩來著色。 程式碼如下所示。
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(mtrl) );
D3DLIGHT9 light;
ZeroMemory( &light, sizeof(light) );
light.Type = D3DLIGHT_DIRECTIONAL;
D3DXVECTOR3 vecDir;
vecDir = D3DXVECTOR3(0.5f, 0.0f, -0.5f);
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
light.Specular.r = 1.0f;
light.Specular.g = 1.0f;
light.Specular.b = 1.0f;
light.Specular.a = 1.0f;
light.Range = 1000;
light.Falloff = 0;
light.Attenuation0 = 1;
light.Attenuation1 = 0;
light.Attenuation2 = 0;
m_pd3dDevice->SetLight( 0, &light );
m_pd3dDevice->LightEnable( 0, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
mtrl.Specular.r = 0.5f;
mtrl.Specular.g = 0.5f;
mtrl.Specular.b = 0.5f;
mtrl.Specular.a = 0.5f;
mtrl.Power = 20;
m_pd3dDevice->SetMaterial( &mtrl );
m_pd3dDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
根據方程式,為物件端點產生的色彩是材質色彩和淺色的組合。
下列兩圖顯示反射材料色彩 (灰色),以及反射淺色 (白色)。
下圖顯示結果反射強光。
結合反射強光與周遭環境和擴散光源會產生下圖。 在套用所有三種光源類型時,這更加清楚地類似寫實物件。
反射光源比擴散光源需要較多運算資源。 這通常用來提供表面材料的視覺線索。 根據表面材料,反射強光在大小和色彩上不同。
相關主題