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


Вершинный туман (Direct3D 9)

Когда система выполняет запотевание вершин, она применяет вычисления тумана к каждой вершине в многоугольнике, а затем интерполирует результаты по всей поверхности многоугольника во время растеризации. Эффекты тумана вершин вычисляются подсистемой освещения и преобразования Direct3D. Дополнительные сведения см. в разделе Туманные параметры (Direct3D 9).

Если приложение не использует Direct3D для преобразования и освещения, оно должно выполнять вычисления тумана. В этом случае поместите коэффициент тумана, вычисляемый в альфа-компоненте зеркального цвета для каждой вершины. Вы можете использовать любые формулы— на основе диапазона, объемных или иных. Direct3D использует предоставленный коэффициент тумана для интерполяции по поверхности каждого многоугольника. Приложения, которые выполняют собственное преобразование и освещение, также должны выполнять собственные вычисления вершинного тумана. В результате такому приложению необходимо включить только наложение тумана и задать цвет тумана с помощью связанных состояний отрисовки, как описано в разделах Туманное наложение (Direct3D 9) и Цвет тумана (Direct3D 9) .

Примечание

При использовании вершинного шейдера необходимо использовать вершинный туман. Для этого используется вершинный шейдер для записи интенсивности тумана для каждой вершины в регистр oFog. После завершения работы пиксельного шейдера данные oFog используются для линейной интерполяции с цветом тумана. Эта интенсивность недоступна в пиксельном шейдере.

 

туман Range-Based

Примечание

Direct3D использует вычисления тумана на основе диапазона только при использовании тумана вершин с подсистемой преобразования Direct3D и освещения. Это связано с тем, что в драйвере устройства реализован пиксельный туман, и в настоящее время не существует оборудования для поддержки тумана на основе диапазона пикселей. Если приложение выполняет собственное преобразование и освещение, оно должно выполнять собственные вычисления тумана, основанные на диапазоне или иным образом.

 

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

схема двух точек зрения и их влияния на туман для двух объектов

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

Если текущее устройство поддерживает туман на основе диапазона, оно устанавливает значение D3DPRASTERCAPS_FOGRANGE в элементе RasterCaps D3DCAPS9 при вызове метода IDirect3DDevice9::GetDeviceCaps . Чтобы включить туман на основе диапазона, задайте для D3DRS_RANGEFOGENABLE состояние отрисовки значение TRUE.

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

Использование вершинного тумана

Чтобы включить туман вершин в приложении, выполните следующие действия.

  1. Включите смешивание тумана, задав для D3DRS_FOGENABLE значение TRUE.
  2. Задайте цвет тумана в D3DRS_FOGCOLOR состоянии отрисовки.
  3. Выберите нужную формулу тумана, задав для D3DRS_FOGVERTEXMODE состояние отрисовки член перечисленного типа 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 принимает только значения DWORD во втором параметре. Этот пример успешно предоставляет значения с плавающей запятой для этих методов без преобразования данных путем приведения адресов переменных с плавающей запятой в качестве указателей DWORD, а затем разыменовывая их.

Типы тумана