頂点フォグ (Direct3D 9)

システムが頂点 fogging を実行すると、ポリゴンの各頂点にフォグ計算が適用され、ラスタライズ中にポリゴンの表面で結果を補間します。 頂点フォグ効果は、Direct3D ライティングおよび変換エンジンによって計算されます。 詳細については、「 フォグパラメーター (Direct3D 9)」を参照してください。

アプリケーションが変換とライティングに Direct3D を使用していない場合、アプリケーションはフォグの計算を実行する必要があります。 この場合は、各頂点の反射色のアルファ成分で計算されるフォグ係数を配置します。 範囲ベース、容量、またはそれ以外の任意の数式を自由に使用できます。 Direct3D は、指定されたフォグ係数を使用して、各多角形の表面を補間します。 独自の変換と照明を実行するアプリケーションでは、独自の頂点フォグ計算も実行する必要があります。 そのため、このようなアプリケーションでは、フォグブレンドを有効にするだけで、フォグ ブレンド (direct3d 9)霧 color (direct3d 9)で説明されているように、関連するレンダリング状態を使用してフォグ色を設定する必要があります。

注意

頂点シェーダーを使用する場合は、頂点フォグを使用する必要があります。 これは、頂点シェーダーを使用して、頂点ごとのフォグの輝度を oFog レジスタに書き込むことで実現されます。 ピクセルシェーダーが完了したら、oFog データを使用して、霧の色で直線的に補間します。 この濃度は、ピクセルシェーダーでは使用できません。

Range-Based 霧

注意

Direct3d は、Direct3D 変換および照明エンジンで頂点フォグを使用する場合にのみ、範囲ベースのフォグ計算を使用します。 これは、ピクセルフォグがデバイスドライバーに実装されており、現在、ピクセルごとの範囲に基づくフォグをサポートするハードウェアが存在しないためです。 アプリケーションが独自の変換とライティングを実行する場合は、独自のフォグ計算、範囲ベース、またはそれ以外の処理を実行する必要があります。

場合によっては、フォグを使用すると、オブジェクトを nonintuitive 方法で霧色とブレンドするグラフィック成果物が導入されることがあります。 たとえば、2つの可視オブジェクトがあるシーンがあるとします。1つはフォグの影響を受け、もう一方は影響を受けないようにします。 表示領域を所定の位置に回転させると、オブジェクトが静止している場合でも、明らかに見える霧効果が変化する可能性があります。 次の図は、このような状況のトップダウンビューを示しています。

2つのビューポイントと、2つのオブジェクトのフォグに与える影響の図

範囲ベースのフォグは、霧効果を判断するためのもう1つの正確な方法です。 範囲ベースのフォグでは、Direct3D は、視点からの実際の距離を、フォグ計算のために頂点に使用します。 Direct3D は、2つの点の間の距離がシーン内の頂点の深さではなく増加するため、フォグの効果が向上します。これにより、回転のアーティファクトが回避されます。

現在のデバイスで範囲ベースのフォグがサポートされている場合は、 _ IDirect3DDevice9:: GetDeviceCapsメソッドを呼び出すと、 D3DCAPS9の RasterCaps メンバーに D3DPRASTERCAPS の値が設定されます。 範囲ベースのフォグを有効にするには、D3DRS _ rangefogenable レンダー状態を TRUE に設定します。

範囲ベースのフォグは、変換およびライティング中に Direct3D によって計算されます。 Direct3D 変換と照明エンジンを使用しないアプリケーションでは、独自の頂点フォグ計算も実行する必要があります。 この場合は、各頂点のスペキュラ成分のアルファ成分に範囲ベースのフォグ係数を指定します。

頂点フォグの使用

アプリケーションで頂点フォグを有効にするには、次の手順に従います。

  1. D3DRS を TRUE に設定して、フォグブレンドを有効に _ します。
  2. D3DRS のレンダー状態で霧の色を設定 _ します。
  3. D3DRS の _ レンダー状態を D3DFOGMODE 列挙型のメンバーに設定して、目的のフォグ式を選択します。
  4. レンダー状態で選択されたフォグ式のフォグパラメーターを必要に応じて設定します。

C++ で記述された次の例は、これらの手順がコードでどのように表示されるかを示しています。

// 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 SetupVertexFog(DWORD Color, DWORD Mode, BOOL UseRange, FLOAT Density)
{
    float Start = 0.5f,    // Linear fog distances
          End   = 0.8f;
 
    // Enable fog blending.
    g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
 
    // Set the fog color.
    g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);
    
    // Set fog parameters.
    if(D3DFOG_LINEAR == Mode)
    {
        g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start));
        g_pDevice->SetRenderState(D3DRS_FOGEND,   *(DWORD *)(&End));
    }
    else
    {
        g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density));
    }

    // Enable range-based fog if desired (only supported for
    //   vertex fog). For this example, it is assumed that UseRange
    //   is set to a nonzero value only if the driver exposes the 
    //   D3DPRASTERCAPS_FOGRANGE capability.
    // Note: This is slightly more performance intensive
    //   than non-range-based fog.
    if(UseRange)
        g_pDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);
}

IDirect3DDevice9:: SetRenderStateメソッドでは、2番目のパラメーターでのみ DWORD 値を受け入れる場合でも、一部のフォグパラメーターは浮動小数点値として必要です。 この例では、浮動小数点変数のアドレスを DWORD ポインターとしてキャストし、逆参照することによって、これらのメソッドに浮動小数点値を正常に変換します。

フォグ型