ピクセル 霧 (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,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 に浮動小数点値を提供します。

霧の種類