共用方式為


像素霧 (Direct3D 9)

像素霧會從裝置驅動程式中每像素計算的事實中取得其名稱。 這與頂點霧霧不同,在轉換和光源計算期間由管線計算。 像素霧有時稱為數據表霧,因為某些驅動程式會使用預先計算的查閱表格來判斷霧因數,並使用每個圖元的深度來套用在混合計算中。 您可以使用 D3DFOGMODE 列舉型別成員所識別的任何霧公式來套用。 這些公式的實作是驅動程式特定的。 如果驅動程式不支援複雜的霧公式,它應該會降級為較不複雜的公式。

Eye-Relative 與 Z 型深度

為了緩解深度緩衝區中 z 值分佈不平均所造成的霧相關圖形成品,大部分的硬體裝置會使用眼部相對深度,而不是以 z 為基礎的圖元霧深度值。 眼睛相對深度基本上是同質座標集中的 w 元素。 Microsoft Direct3D 會從設定為重現 true w 的裝置空間座標取得 RHW 元素的倒數。 如果裝置支援眼睛相對霧,當您呼叫 IDirect3DDevice9::GetDeviceCaps 方法時,它會在 D3DCAPS9 結構的 RasterCaps 成員中設定 D3DPRASTERCAPS_WFOG 旗標。 除了參考轉譯器之外,軟體裝置一律會使用 z 來計算圖元霧效果。

支援眼睛相對霧時,如果提供的投影矩陣在世界空間中產生 z 值,相當於裝置空間中的 w 值,系統會自動使用眼睛相對深度,而不是 z 型深度。 您可以使用 D3DTS_PROJECTION 值,並傳遞代表所需矩陣的 D3DMATRIX 結構,藉此呼叫 IDirect3DDevice9::SetTransform 方法來設定投影矩陣。 如果投影矩陣不符合此需求,則不會正確套用霧效果。 如需產生相容矩陣的詳細資訊,請參閱 投影轉換 (Direct3D 9)

Direct3D 會在其 w 型深度計算中使用目前設定的投影矩陣。 因此,應用程式必須設定相容的投影矩陣,才能接收所需的 w 型功能,即使它不使用 Direct3D 轉換管線也一樣。

Direct3D 會檢查投影矩陣的第四個數據行。 如果係數為 [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 方法只接受第二個參數中的 DWORD 值,還是需要一些霧化參數作為浮點值。 上述範例會提供浮點值來 IDirect3DDevice9::SetRenderState,而不需要數據轉譯,方法是將浮點變數的位址轉換成 DWORD 指標,然後取值。

霧類型