スペキュラ ライト
スペキュラ ライト
スペキュラ反射をモデル化するには、光の進行方向だけでなく、視点からの視線の方向もシステムに知らせる必要がある。システムでは Phong スペキュラ反射モデルの簡易バージョンを使う。このモデルでは、ハーフ ベクトルを使ってスペキュラ反射強度を概算する。
デフォルトのライティング ステートでは、スペキュラ ハイライトを計算しない。スペキュラ ライティングを有効にするには、D3DRS_SPECULARENABLE を TRUE に設定する必要がある。
スペキュラ ライティングの方程式
スペキュラ ライティングは次の方程式によって記述される。
スペキュラ ライティング = Cs*sum[Ls*(N.H)P*Atten*Spot] |
次の表で、変数と、その型および範囲を示す。
パラメータ | デフォルト値 | 型 | 説明 |
---|---|---|---|
Cs | (0,0,0,0) | D3DCOLORVALUE | スペキュラ色。 |
sum | N/A | N/A | 各ライトのスペキュラ成分の合計。 |
N | N/A | D3DVECTOR | 頂点の法線。 |
H | N/A | D3DVECTOR | ハーフ ベクトル。「ハーフ ベクトル」を参照すること。 |
P | 0.0 | FLOAT | スペキュラ反射の強度。範囲は 0 ~ 正の無限大。 |
Ls | (0,0,0,0) | D3DCOLORVALUE | ライトのスペキュラ色。 |
Atten | N/A | FLOAT | ライトの減衰値。「減衰とスポットライト係数」を参照すること。 |
Spot | N/A | FLOAT | スポットライト係数。「減衰とスポットライト係数」を参照すること。 |
Cs の値は次のいずれかである。
- 頂点色 1 (SPECULARMATERIALSOURCE = D3DMCS_COLOR1 で、頂点の宣言で最初の頂点色を指定した場合)
- 頂点色 2 (SPECULARMATERIALSOURCE = D3DMCS_COLOR2 で、頂点の宣言で 2 番目の頂点色を指定した場合)
- マテリアルのスペキュラ色
注 いずれかの SPECULARMATERIALSOURCE オプションが使われていて、頂点色が指定されていない場合は、マテリアルのスペキュラ色を使う。
すべてのライトが処理され、個別に補間された後、スペキュラ成分は 0 ~ 255 にクランプされる。
ハーフ ベクトル
ハーフ ベクトル (H) は、オブジェクトの頂点から光源へのベクトルと、オブジェクトの頂点からカメラ位置へのベクトルの、2 つのベクトルの中間に存在する。Microsoft® Direct3D® では、2 つの方法でハーフ ベクトルを計算する。D3DRS_LOCALVIEWER を TRUE に設定すると、システムではライティングの方向ベクトルに加えて、カメラの位置と頂点の位置を使ってハーフ ベクトルを計算する。次の公式はこの計算を示す。
H = norm(norm(Cp - Vp) + Ldir) |
パラメータ | デフォルト値 | 型 | 説明 |
---|---|---|---|
Cp | N/A | D3DVECTOR | カメラの位置。 |
Vp | N/A | D3DVECTOR | 頂点の位置。 |
Ldir | N/A | D3DVECTOR | 頂点の位置からライトの位置への方向ベクトル。 |
この方法でハーフ ベクトルを決定する場合は、計算負荷が大きくなることがある。もう 1 つの方法は、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 = 1.0f; mtrl.Specular.g = 1.0f; mtrl.Specular.b = 1.0f; mtrl.Specular.a = 1.0f; mtrl.Power = 20; m_pd3dDevice->SetMaterial( &mtrl; ); m_pd3dDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
方程式に従うと、オブジェクト頂点の色は、マテリアル色とライティング色を組み合わせた色になる。
次の 2 つの画像は、グレーのマテリアル色と白いライティング色を示している。
この結果、次に示すようなスペキュラ ハイライトになる。
このスペキュラ ハイライトをアンビエント ライティングおよびディフューズ ライティングと組み合わせると、次のような画像ができる。この 3 種類のライティングをすべて適用することによって、オブジェクトはよりリアルになる。
スペキュラ ライティングは、ディフューズ ライティングよりも計算の負荷が大きい。通常、スペキュラ ライティングは、サーフェイスのマテリアルに関する視覚的な手がかりを提供するために使われる。スペキュラ ハイライトのサイズおよび色は、サーフェイスのマテリアルによって変化する。