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

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

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

Примечание

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

 

Range-Based Туман

Примечание

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

 

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

diagram of two viewpoints and how they affect fog for two objects

Туман на основе диапазона — это еще один, более точный способ определения эффектов тумана. В тумане на основе диапазона 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);
}

Некоторые параметры тумана требуются в качестве значений с плавающей запятой, хотя метод IDirect3Device9::SetRenderState принимает только значения DWORD во втором параметре. В этом примере значения с плавающей запятой успешно предоставляются этим методам без преобразования данных путем приведения адресов переменных с плавающей запятой в качестве указателей DWORD, а затем разыменовывать их.

Типы тумана