DirectX 7 の Direct3D におけるライト

Microsoft Corporation

June 2000

はじめに

Microsoft® Direct3D® のシーンにおける要素の見え方は、さまざまな変数で制御されています。そのような変数のひとつがオブジェクトに与えられるマテリアル属性です。マテリアルは、ライトの処理方法やテクスチャを使用するかどうかも含め、サーフェイスの光り方や色の属性を記述します。マテリアルの詳細については、Microsoft® DirectX® SDK を参照してください。

Direct3D アプリケーションのサーフェイスは、ユーザーが作成したライトとマテリアルによりある色で発色します。ここでは、Direct3D アプリケーション プログラマ向けに、ライティング パラメータの使用方法と頂点 カラーの計算方法について解説します。その他のライトやフォグについての詳細、および、ライティングに関するヒントについては、『Direct3D SDK』を参照してください

Version 6.0 後の Direct3D における変更

Direct3D は、未ライティングの頂点ごとにカラーを計算します。この計算には、クライアント指定のライティング モデルと頂点座標を含めることのできるパラメータ セット、光源のパラメータ、法線、そしてカレント マテリアルで定義した式が用いられます。次のリストは、DirectX 6 以降の Direct3D の変更箇所をまとめたものです。

  • D3DLIGHTSTATE をなくしました。

  • ライト オブジェクトとマテリアル オブジェクトをなくしました。

  • 新しい API 機能がデバイスに追加されました。 SetLight(), GetLight(), LightEnable(), GetLightEnable()

  • dwFlags は D3DLIGHT7 構造体 から削除されました。

  • D3DLIGHT7 構造体にアンビエント カラーとスペキュラ カラーが追加されました。

  • D3DLIGHT_PARALLELPOINT をなくしました。

また、DirectX 7 デバイス オブジェクトには、次に示すライティング ステートが追加されました。

  • カレントアンビエント カラー

  • カレント マテリアル

  • ライト アレイ

  • 頂点カラー モード ステート

  • ライティング有効ステート

  • 頂点カラー有効ステート

  • 頂点フォグ モード

新しいライティング API

表 1. Direct3D Version 7 のライティング API

レンダリングステート 意味 範囲 既定値
ライティング ライティングの有効/無効 TRUE、FALSE TRUE
SPECULAR有効 スペキュラ コンポーネントの計算の有効/無効 TRUE、FALSE TRUE
COLORVERTEX 頂点 カラーの使用の有効/無効 TRUE、FALSE TRUE
LOCALVIEWER ビューアがローカルまたは無限 TRUE、FALSE TRUE
NORMALIZENORMALS カメラ空間に法線を変換後、Direct3Dによって正規化される必要があるかどうかを定義 TRUE、FALSE FALSE
AMBIENT アンビエント シーン カラー D3DCOLOR 0
FOGENABLE フォグの有効/無効 TRUE、FALSE FALSE
FOGVERTEXMODE フォグ 頂点 モード D3DFOGMODE D3DFOG_NONE
FOGTABLEMODE ピクセル単位フォグ モード D3DFOGMODE D3DFOG_NONE
FOGTABLESTART リニア フォグのフォグの始点 D3DVALUE

(-∞, +∞)

0.0
FOGTABLEEND リニア フォグのフォグの終点 D3DVALUE

(-∞, +∞)

1.0
FOGTABLEDENSITY 指数フォグの密度係数 [0.0, 1.0] 1.0
RANGEFOGENABLE カメラから頂点までの距離修正計算の有効/無効 TRUE、FALSE FALSE

D3DFOGMODE は列挙子: D3DFOG_NONE、D3DFOG_LINEAR、D3DFOG_EXP、D3DFOG_EXP2.

HRESULT SetMaterial(D3DMATERIAL7*)

デバイスの作成時に、カレント マテリアルは、次のような既定値に設定されます。

  • diffuse (1,1,1)

  • specular (0,0,0)

  • ambient (0,0,0)

  • emissive (0,0,0)

  • power (0)

HRESULT SetLight (DWORD dwLightIndex, D3DLIGHT7*)

dwLightIndex インデックスでライトのライト パラメータを設定します。Direct3D では、メモリ容量による制限を除けば、数限りなくライトを使用できますが、連続したライト インデックスを使用してください。なお、有効なライト数は、ハードウェアによっても制限されます。

SetLight だけでは、ライトは有効になりません。ライトを有効にするには、LigntEnable を呼び出します。

HRESULT  GetLight (DWORD dwLightIndex, D3DLIGHT7*)

HRESULT LightEnable(DWORD dwLightIndex, BOOL bEnable)

これにより、dwLightIndex インデックス付きのライトの有効、無効を設定します。ライトを有効に設定したとき、事前にセットアップされていない場合は、次のような既定値に初期化されます。

  • dltType D3DLIGHT_DIRECTIONAL

  • dcvColor (1,1,1,0)

  • dcvSpecular (0,0,0,0)

  • dcvAmbient (0,0,0,0)

  • dvPosition (0,0,0)

  • dvDirection (0,0,1)

  • dvRange (0)

  • dvFalloff  (0)

  • dvAttenuation0 (0)

  • dvAttenuation1 (0)

  • dvAttenuation2 (0)

  • dvTheta (0)

  • dvPhi (0)

HRESULT Ge LightEnable(DWORD dwLightIndex, BOOL *bEnable)

頂点カラー

一般に、ライティング論理式では、マテリアル カラーを使用しますが、ユーザーの設定により、マテリアル カラー (エミッション、アンビエント、ディフューズ、およびスペキュラ) よりも、ディフューズ頂点 カラーやスペキュラ頂点 カラーを優先させることができます。

これを、次のレンダリングステートで制御します。

表 2. マテリアル カラー ソースのレンダリング ステート

レンダリング ステート 意味 タイプ 既定値
AMBIENTMATERIALSOURCE アンビエント マテリアル カラーのソースを定義 D3DMATERIALCOLORSOURCE D3DMCS_MATERIAL
DIFFUSEMATERIALSOURCE ディフューズ マテリアル カラーのソースを定義 D3DMATERIALCOLORSOURCE D3DMCS_COLOR1
SPECULARMATERIALSOURCE スペキュラ マテリアル カラーのソースを定義 D3DMATERIALCOLORSOURCE D3DMCS_COLOR2
EMISSIVEMATERIALSOURCE エミッション マテリアル カラーのソースを定義 D3DMATERIALCOLORSOURCE D3DMCS_MATERIAL
COLORVERTEX 頂点 カラー使用の無効/有効 BOOL TRUE

アルファ/透過値は、つねにディフューズ カラーのアルファ チャンネルの値を使用します。

フォグ値は、つねにスペキュラ カラーのアルファ チャンネルの値を使用します。

D3DMATERIALCOLORSOURCE の値は、次のとおりです。

  • D3DMCS_MATERIAL - ソースにマテリアル カラーを使用

  • D3DMCS_COLOR1 - ソースにディフューズ頂点 カラーを使用

  • D3DMCS_COLOR2 - ソースにスペキュラ頂点 カラーを使用

ライティングパラメータ

次の表は、ライティング式に使用するパラメータをまとめたものです。各パラメータごとにタイプ、既定値、指定できる値の範囲があります。

表 3. ライティング式のパラメータ

パラメータ 既定値 タイプ 解説

Pe

(0,0,0)

D3DVECTOR

カメラ空間におけるカメラの位置

Po

 なし

D3DVECTOR

カメラ空間におけるカレント モデル原点 (0,0,0,1) (これは、 Mw*Mv マテリアルの 4行目)

Mw

なし

D3DMATRIX

ワールド行列、D3DTRANSFORMSTATE_WORLD で設定

Mv

なし

D3DMATRIX

ビュー行列、D3DTRANSFORMSTATE_VIEW で設定

Mwv

なし

D3DMATRIX

Mw*Mv

Halfway

なし

D3DVECTOR

正規化ベクトル、スペキュラ反射の計算に使用

La

(0.0, 0.0, 0.0, 0.0)

D3DCOLORVALUE

ライト ステートのアンビエント カラー。
D3DRENDERSTATE_AMBIENT で設定

V

なし

D3DVECTOR

カメラ空間における頂点の位置

N

なし

D3DVECTOR

カメラ空間の正規化された頂点法線

Vcd

なし

D3DCOLORVALUE

ディフューズ頂点 カラー

Vcs

なし

D3DCOLORVALUE

スペキュラ頂点 カラー

マテリアル パラメータ

次の表は、マテリアルで使用するパラメータです。各パラメータには、対応するタイプ、既定値、指定できる値の範囲があります。

表 4. マテリアル パラメータ

パラメータ 既定値 タイプ 解説

Ma

(0.0, 0.0, 0.0, 0.0)

D3DCOLORVALUE

アンビエント カラー

Md

(255,255, 255,255)

D3DCOLORVALUE

ディフューズ カラー

Ms

(0.0, 0.0, 0.0, 0.0)

D3DCOLORVALUE

スペキュラ カラー

Me

(0.0, 0.0, 0.0, 0.0)

D3DCOLORVALUE

エミッション カラー

Mp

0.0

D3DVALUE

スペキュラ指数。範囲: (-∞, +∞)

光源 i パラメータ

次の表は、光源 i パラメータをまとめたものです。各パラメータには、対応するタイプ、既定値、指定できる値の範囲があります。

表 5. 光源 i パラメータ

パラメータ 既定値 タイプ 解説

LpI

(0.0, 0.0, 0.0)

D3DVECTOR

カメラ空間における位置

LdI

(0.0, 0.0, 1.0)

D3DVECTOR

カメラ空間におけるライトまでの方向

LrI

0.0

D3DVALUE

距離の範囲。範囲:

 [0.0, D3DLIGHT_RANGE_MAX]

LcaI

(0.0, 0.0, 0.0, 0.0)

D3DCOLORVALUE

アンビエント カラー

LcsI

(0.0, 0.0, 0.0, 0.0)

D3DCOLORVALUE

スペキュラ カラー

LcI

(1.0, 1.0, 1.0, 0.0)

D3DCOLORVALUE

ディフューズ カラー

att0i

0.0

D3DVALUE

定減衰係数。範囲:

 (0, +∞)

att1I

0.0

D3DVALUE

一次減衰係数。範囲:

 (0, +∞)

att2I

0.0

D3DVALUE

二次減衰係数。範囲:

 (0, +∞)

falloffI

0.0

D3DVALUE

減衰係数。範囲: (-∞, +∞)

thetaI

0.0

D3DVALUE

スポットライトの真影部角度。単位ラジアン。範囲: [0, π)

phiI

0.0

D3DVALUE

スポットライトの半影部角度。単位ラジアン。範囲: [thetai, π)

表記法

  • D3DCOLORVALUE コンポーネントの範囲は、(-∞, +∞)です。

Cc973415.dx7light12(ja-jp,MSDN.10).gif

  • ? - 内積は、 d1 ? d2 = max{d1?d2,  0} で定義します。

  • norm(P) - 正規化ベクトル

  • V1V2 - 点 V1 から点 V2 までのベクトル

  • M -1 - 逆行列

  • M T- トランスフォーム行列

  • V1 / V2 は、次のベクトルと等価です。ここで V1V2 は、 D3DVECTOR タイプです。 (V1.x / V2.x,  V1.y / V2.y , V1.z / V2.z).

  • V1 * V2 は、次のベクトルと等価です。ここで V1V2 は、D3DVECTOR タイプです。 (V1.x * V2.x,  V1.y * V2.y , V1.z * V2.z).

カメラ空間への変換

カメラ空間における頂点は、オブジェクト 頂点に Mwv 行列を乗じて算出します。

  V = Vobject * Mwv

カメラ空間における法線は、オブジェクト法線に、逆変換した Mwv 行列を乗じ、結果を正規化して算出します。

  N = Nobject * (Mwv
-1)T

If D3DRENDERSTATE_NORMALIZENORMALS が TRUE に設定されているとき、カメラ空間に対する変換後に法線は正規化されます。

N = norm(N)

カメラ空間におけるライトの位置は (Lpi ) 光源位置に Mv を乗じて算出します。

Lpi  = Lpiorginal * Mv

D3DLIGHT_DIRECTIONAL ライトの場合、カメラ空間におけるライトまでの方向は、光源の位置に Mv 行列を乗じて算出し、結果を正規化しマイナスをつけます。

Ldi  = -norm(Ldiorginal * Mv)

D3DLIGHT_POINT と D3DLIGHT_SPOT の場合、ライトまでの方向は、次のように計算します。

Ldi = norm(VLpi)

ライティング論理式

ライティングステージでは、RGBA 論理式のディフューズ (D) カラーと スペキュラ (S) カラーが出力されます。 ライティングには、次の 2 つのステートのどちらかのステートがあります。

  1. ライティング Off (D3DRENDERSTATE_LIGHTING を FALSE に設定)。このステートでは、頂点 カラーを次のように計算します。

    D3DRENDERSTATE_COLORVERTEX は、無視されます。

    ディフューズ頂点 カラーがある場合、出力ディフューズ カラーは、頂点ディフューズカラーになります。ディフューズ頂点 カラーがない場合、ディフューズ カラーは、規定のディフューズ カラー (255,255,255,255) になります。出力ディフューズカラーは、[0, 255] の範囲内でスケールの調整ができます。

    スペキュラ頂点 カラーがある場合、出力スペキュラ カラーはスペキュラ頂点カラーになります。スペキュラ頂点 カラーがない場合、スペキュラ カラーは規定のスペキュラ (0,0,0,0) になります。出力スペキュラカラーは、[0, 255] の範囲内でスケールの調整ができます。

  2. ライティング On (D3DRENDERSTATE_LIGHTING ライティングを TRUE に設定)。このステートでは、Direct3D は次の論理式により頂点 カラーを計算します。

    法線が頂点にない場合、内積に依存するライティング式の部分はゼロに設定されます。これでもライティングの計算は実行されます。

    ライティングは、カメラ空間で実行されます。

    次のライティング式では、アルファ コンポーネントを使用しません。

Cc973415.dx7light1(ja-jp,MSDN.10).gif

Cc973415.dx7light2(ja-jp,MSDN.10).gif

図 1. 出力ディフューズカラー

D3DRENDERSTATE_SPECULARENABLE が FALSE に設定されている場合、スペキュラ コンポーネントは (0,0,0,0) に設定されます。それ以外の場合は、次のように計算します。

Cc973415.dx7light3(ja-jp,MSDN.10).gif

Cc973415.dx7light4(ja-jp,MSDN.10).gif

ここで

Cc973415.dx7light5(ja-jp,MSDN.10).gif

Cc973415.dx7light6(ja-jp,MSDN.10).gif

Cc973415.dx7light7(ja-jp,MSDN.10).gif

Cc973415.dx7light8(ja-jp,MSDN.10).gif

図 2. 出力スペキュラ カラー

hi は、法線とライト方向ベクトルとの中心ベクトルです。

hi = norm(norm(VPe) + Ldi ))    , if D3DRENDERSTATE_LOCALVIEWER が TRUE の場合

norm((0,0,-1) + Ldi )), if D3DRENDERSTATE_LOCALVIEWER が FALSE の場合

Cc973415.dx7light9(ja-jp,MSDN.10).gif

Cc973415.dx7light10(ja-jp,MSDN.10).gif

di は、頂点からライト i までの距離であり、次のように計算します。

Cc973415.dx7light11(ja-jp,MSDN.10).gif

ディフューズ コンポーネントとスペキュラ コンポーネントの範囲は、すべてのライトが処理され、別々に補間された後に 0 から 255 になります。