ピクセル 霧 (Direct3D 9)

ピクセル 霧は、デバイス ドライバーのピクセル単位で計算されるという事実からその名前を取得します。 これは、変換と照明の計算中にパイプラインによって計算される頂点霧とは異なります。 ピクセル の霧はテーブル の霧と呼ばれることもあります。一部のドライバーは、事前計算された参照テーブルを使用して霧の係数を決定し、各ピクセルの深度を使用してブレンド計算に適用するためです。 これは、D3DFOGMODE 列挙型のメンバーによって識別される任意の霧式を使用して適用できます。 これらの数式の実装はドライバー固有です。 ドライバーが複雑な霧の数式をサポートしていない場合は、より複雑な数式に低下する必要があります。

Eye-Relativeと Z ベースの深度

深度バッファー内の z 値の不均一な分布によって発生する霧関連のグラフィックアーティファクトを軽減するために、ほとんどのハードウェア デバイスでは、ピクセル の霧に対して z ベースの深度値ではなく、視線相対深度が使用されます。 視線相対深度は、基本的に同種座標セットからの w 要素です。 Microsoft Direct3D は、デバイス空間座標セットから RHW 要素の逆数を受け取り、真の w を再現します。 デバイスで視線相対霧がサポートされている場合は、IDirect3DDevice9::GetDeviceCaps メソッドを呼び出すときに、D3DCAPS9 構造体の RasterCaps メンバーにD3DPRASTERCAPS_WFOG フラグが設定されます。 参照ラスタライザーを除き、ソフトウェア デバイスは常に z を使用してピクセル の霧効果を計算します。

視線相対霧がサポートされている場合、指定された投影行列でワールド空間の z 値が生成され、デバイス空間の w 値と同等の場合、システムは z ベースの深さではなく、視線相対深度を自動的に使用します。 射影行列を設定する場合 は、IDirect3DDevice9::SetTransform メソッドを呼び出し、D3DTS_PROJECTION値を使用し、目的の行列を表す D3DMATRIX 構造体を渡します。 射影行列がこの要件に準拠していない場合、霧効果は正しく適用されません。 準拠マトリックスの生成の詳細については、「 プロジェクション変換 (Direct3D 9)」を参照してください。

Direct3D では、現在設定されている射影行列を使って w ベース深度の計算を実行します。 その結果、アプリケーションは、Direct3D 変換パイプラインを使用しない場合でも、必要な w ベースの特徴を受け取るように準拠したプロジェクション マトリックスを設定する必要があります。

Direct3D は、射影行列の 4 番目の列をチェックします。 係数が [0,0,0,0,1] の場合 (アフィン投影の場合)、システムは霧に z ベースの深度値を使用します。 この場合は、デバイス空間の線形霧効果の開始距離と終了距離も指定する必要があります。この範囲は、ユーザーに最も近いポイントでは 0.0、最も遠いポイントでは 1.0 です。

ピクセル 霧の使用

アプリケーションでピクセル 霧を有効にするには、次の手順に従います。

  1. D3DRS_FOGENABLEのレンダリング状態を TRUE に設定して、霧のブレンドを有効にします。
  2. D3DRS_FOGCOLORレンダリング状態で目的の霧の色を設定します。
  3. D3DRS_FOGTABLEMODEレンダリング状態を D3DFOGMODE 列挙型の対応するメンバーに設定して、使用する霧の数式を選択します。
  4. 関連付けられたレンダリング状態で選択した霧モードに対して必要に応じて、霧パラメータを設定します。 これには、線形霧の開始距離と終了距離、指数霧モードの霧密度が含まれます。

次の例は、これらの手順がコード内でどのようなものになるかを示しています。

// For brevity, error values in this example are not checked 
//   after each call. A real-world application should check 
//   these values appropriately.
//
// For the purposes of this example, g_pDevice is a valid
//   pointer to an IDirect3DDevice9 interface.
void SetupPixelFog(DWORD Color, DWORD Mode)
{
    float Start   = 0.5f;    // For linear mode
    float End     = 0.8f;
    float Density = 0.66f;   // For exponential modes
 
    // Enable fog blending.
    g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
 
    // Set the fog color.
    g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);
    
    // Set fog parameters.
    if( Mode == D3DFOG_LINEAR )
    {
        g_pDevice->SetRenderState(D3DRS_FOGTABLEMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start));
        g_pDevice->SetRenderState(D3DRS_FOGEND,   *(DWORD *)(&End));
    }
    else
    {
        g_pDevice->SetRenderState(D3DRS_FOGTABLEMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density));
    }

IDirect3DDevice9::SetRenderState メソッドが 2 番目のパラメーターで DWORD 値のみを受け取る場合でも、一部の霧パラメーターは浮動小数点値として必要です。 前の例では、浮動小数点変数のアドレスを DWORD ポインターとしてキャストし、逆参照することで、データ変換なしで IDirect3DDevice9::SetRenderState に浮動小数点値を提供します。

霧の種類