反射照明 (Direct3D 9)

反射反射をモデリングするには、光が進行している方向だけでなく、視聴者の目への方向もシステムで認識されている必要があります。 システムはフォン反射光モデルの簡易版を使用します。これは、中間ベクトルを使用して、反射光のおおよその強さを計算します。

既定の光源の状態では、反射光は計算されません。 反射照明を有効にするには、必ずD3DRS_SPECULARENABLE を TRUE に設定してください。

反射光の方程式

反射照明は次の式で表されます。

反射照明 = Cs * sum[Ls * (N ·H)P * Atten * Spot]

 

次の表は、変数、型、およびそれらの範囲を示しています。

パラメーター 既定値 説明
Cₛ (0,0,0,0) D3DCOLORVALUE 反射の色。
Sum 該当なし 該当なし 各ライトの鏡面コンポーネントの総和。
× 該当なし D3DVECTOR 頂点法線。
H 該当なし D3DVECTOR 中間ベクトル。 中間ベクトルのセクションを参照してください。
P 0.0 FLOAT 鏡面反射の係数。 範囲は 0 から +infinity です。
Lₚ (0,0,0,0) D3DCOLORVALUE 明るい鏡面色。
Atten 該当なし FLOAT 光の減衰値。 「減衰とスポットライト係数 (Direct3D 9)」を参照してください。
スポット 該当なし FLOAT スポットライト係数。 「減衰とスポットライト係数 (Direct3D 9)」を参照してください。

 

Cₛ の値は以下のどちらかになります。

if(SPECULARMATERIALSOURCE == D3DMCS_COLOR1)
  C = color1;
  • 頂点 color1(反射マテリアル ソースがD3DMCS_COLOR1で、頂点宣言で最初の頂点の色が指定されている場合)。
  • 頂点 color2(反射マテリアル ソースがD3DMCS_COLOR2で、頂点宣言で 2 番目の頂点の色が指定されている場合)。
  • マテリアルの反射色

注意

いずれかの反射マテリアル ソース オプションを使用し、頂点の色を指定しない場合は、マテリアルの反射色が使用されます。

 

反射コンポーネントは、すべての光が個別に処理されて補間されると、0 ~ 255 になるようにクランプされます。

中間ベクトル

中間ベクトル (H) は、オブジェクトの頂点から光源までのベクトルと、オブジェクトの頂点からカメラの市場でのベクトルの 2 つのベクトルの中間に存在しています。 Direct3D では、中間ベクトルの計算に 2 通りの方法を用意しています。 D3DRS_LOCALVIEWER を TRUE に設定すると、カメラの位置と頂点の位置とライトの方向ベクトルを使用して中間ベクトルが計算されます。 これは次の数式で表されます。

H = norm(norm(Cp - Vp) + Ldir)

 

パラメーター 既定値 説明
Cₚ 該当なし D3DVECTOR カメラの位置。
Vₚ 該当なし D3DVECTOR 頂点の位置。
Ldir 該当なし 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);

この方程式では、生成されるオブジェクトの頂点の色は、マテリアルの色と光の色の組み合わせになります。

次の 2 つの図は、鏡面マテリアルの色 (灰色) と、反射光の色 (白) を表しています。

白い球体の灰色の球体のイラスト

生成された反射光は、次の図のようになります。

反射光の図

反射光に環境光と拡散光を追加すると、次の図のようになります。 これら 3 種類の光をすべて使用すると、本物のオブジェクトにより近い表現ができます。

反射光、環境光、拡散光を組み合わせた結果の図

反射光は、拡散光よりも計算の負荷が高くなります。 これは通常、表面の材質についての視覚的な手がかりを提供するために使用されます。 反射光は表面のマテリアルのサイズと色によって変化します。

照明の計算