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 |
ライト ステートのアンビエント カラー。 |
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 コンポーネントの範囲は、(-∞, +∞)です。
? - 内積は、 d1 ? d2 = max{d1?d2, 0} で定義します。
norm(P) - 正規化ベクトル
V1V2 - 点 V1 から点 V2 までのベクトル
M -1 - 逆行列
M T- トランスフォーム行列
V1 / V2 は、次のベクトルと等価です。ここで V1 と V2 は、 D3DVECTOR タイプです。 (V1.x / V2.x, V1.y / V2.y , V1.z / V2.z).
V1 * V2 は、次のベクトルと等価です。ここで V1 と V2 は、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 つのステートのどちらかのステートがあります。
ライティング Off (D3DRENDERSTATE_LIGHTING を FALSE に設定)。このステートでは、頂点 カラーを次のように計算します。
D3DRENDERSTATE_COLORVERTEX は、無視されます。
ディフューズ頂点 カラーがある場合、出力ディフューズ カラーは、頂点ディフューズカラーになります。ディフューズ頂点 カラーがない場合、ディフューズ カラーは、規定のディフューズ カラー (255,255,255,255) になります。出力ディフューズカラーは、[0, 255] の範囲内でスケールの調整ができます。
スペキュラ頂点 カラーがある場合、出力スペキュラ カラーはスペキュラ頂点カラーになります。スペキュラ頂点 カラーがない場合、スペキュラ カラーは規定のスペキュラ (0,0,0,0) になります。出力スペキュラカラーは、[0, 255] の範囲内でスケールの調整ができます。
ライティング On (D3DRENDERSTATE_LIGHTING ライティングを TRUE に設定)。このステートでは、Direct3D は次の論理式により頂点 カラーを計算します。
法線が頂点にない場合、内積に依存するライティング式の部分はゼロに設定されます。これでもライティングの計算は実行されます。
ライティングは、カメラ空間で実行されます。
次のライティング式では、アルファ コンポーネントを使用しません。
図 1. 出力ディフューズカラー
D3DRENDERSTATE_SPECULARENABLE が FALSE に設定されている場合、スペキュラ コンポーネントは (0,0,0,0) に設定されます。それ以外の場合は、次のように計算します。
ここで
図 2. 出力スペキュラ カラー
hi は、法線とライト方向ベクトルとの中心ベクトルです。
hi = norm(norm(VPe) + Ldi )) , if D3DRENDERSTATE_LOCALVIEWER が TRUE の場合
norm((0,0,-1) + Ldi )), if D3DRENDERSTATE_LOCALVIEWER が FALSE の場合
di は、頂点からライト i までの距離であり、次のように計算します。
ディフューズ コンポーネントとスペキュラ コンポーネントの範囲は、すべてのライトが処理され、別々に補間された後に 0 から 255 になります。