Поделиться через


Пиксельный туман (Direct3D 9)

Пиксельный туман получает свое название от того факта, что он вычисляется на основе каждого пикселя в драйвере устройства. Это отличается от тумана вершин, который вычисляется конвейером во время преобразования и вычислений освещения. Пиксельный туман иногда называют табличным туманом, так как некоторые драйверы используют предварительно вычисленную таблицу подстановки для определения коэффициента тумана, используя глубину каждого пикселя для применения в вычислениях смешения. Его можно применить с помощью любой формулы тумана, определяемой элементами перечисленного типа D3DFOGMODE . Реализации этих формул зависят от драйвера. Если драйвер не поддерживает сложную формулу тумана, он должен ухудшиться до менее сложной формулы.

Eye-Relative и глубина на основе Z

Чтобы облегчить графические артефакты, связанные с туманом, вызванные неравномерным распределением значений z в буфере глубины, большинство аппаратных устройств используют относительную глубину взгляда вместо значений глубины на основе Z для пиксельного тумана. Относительная глубина взгляда по сути является элементом w из однородного набора координат. Microsoft Direct3D принимает обратную часть элемента RHW из набора координат пространства устройства для воспроизведения true w. Если устройство поддерживает туман относительно взгляда, оно устанавливает флаг D3DPRASTERCAPS_WFOG в элементе RasterCaps структуры D3DCAPS9 при вызове метода IDirect3DDevice9::GetDeviceCaps . За исключением растеризатора ссылок, программные устройства всегда используют z для вычисления эффектов тумана пикселей.

При поддержке тумана относительного взгляда система автоматически использует глубину относительного взгляда, а не глубину на основе Z, если предоставленная матрица проекции создает z-значения в мировом пространстве, эквивалентные w-значениям в пространстве устройства. Матрицу проекции можно задать путем вызова метода IDirect3DDevice9::SetTransform , используя значение D3DTS_PROJECTION и передав структуру D3DMATRIX , представляющую нужную матрицу. Если матрица проекции не соответствует этому требованию, эффекты тумана применяются неправильно. Дополнительные сведения о создании совместимой матрицы см. в разделе Преобразование проекции (Direct3D 9).

Direct3D использует текущую матрицу проекции при расчетах глубины вершин на основе переменной w. В результате приложение должно задать соответствующую матрицу проекции для получения требуемых функций на основе W, даже если оно не использует конвейер преобразования Direct3D.

Direct3D проверяет четвертый столбец матрицы проекции. Если коэффициенты [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 во втором параметре. В предыдущем примере значения с плавающей запятой предоставляются для IDirect3Device9::SetRenderState без преобразования данных путем приведения адресов переменных с плавающей запятой в качестве указателей DWORD, а затем разыменовки их.

Типы тумана