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


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

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

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

Заметка

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

 

Range-Based Туман

Заметка

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

 

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

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

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

Если текущее устройство поддерживает туман на основе диапазона, оно задает значение D3DPRASTERCAPS_FOGRANGE в элементе RasterCaps D3DCAPS9 при вызове метода IDirect3Device9::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, а затем разоменовки их.

Типы туманов