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

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

Pixel fog

В играх туман появился не от хорошей жизни.
С indoor-окружениями (Doom, Quake etc.) все было просто
и радужно, а вот с открытыми пространствами
возникали заморочки. Дело в том, что железо
прошлого было не в состоянии нарисовать
огромные открытые пространства с кучей
полигонов, поэтому пришлось неизбежно
укоротить видимую дистанцию, т.е.
придвинуть линию горизонта чуть ли не
вплотную. Само собой, этот непростительный
поступок нужно было скрыть от всех и вся,
так вот и пришла в чью-то светлую голову
идея закрыть горизонт слоем непрозрачного
тумана. Апогей сей новаторской мысли, можно
было созерцать в нинтендовском Turok'e, в
котором за туманом даже своего ствола
бывало не видно.

Такой вот вездесущий туман называется
пиксельным туманом (pixel fog, иногда
встречается название distance fog), он
распространяется на все объекты сцены и
реализуется с помощью несложного алгоритма,
который использует значения z-буфера в
линейной (часто) или экспоненциальной (редко)
функции для вычисления цвета пикселя. Для
того чтобы быстро определить нужную
цветовую составляющую вносимую туманом в
цвет пикселя, иногда прибегают к помощи
заранее рассчитанных таблиц тумана (fog tables).
Несмотря на свою примитивность, pixel fog
используется и по сей день во многих
современных игрушках.

В следующих двух примерах я покажу, как
инициализировать такой туман в OpenGL и DirectX
приложениях:

// OpenGL
//
void SetupPixelFog (float Color[4], int Mode)
{
float Start = 4.0f, // для линейного тумана
End = 1000.f,
Density = 0.66; // для экспоненциального

// разрешаем использование тумана
glEnable (GL_FOG);

// устанавливаем цвет
glFogfv(GL_FOG_COLOR, Color);

// устанавливаем параметры
if (Mode == GL_LINEAR) {
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, Start);
glFogf(GL_FOG_END, End);
}
else
{
glFogi(GL_FOG_MODE, Mode);
glFogf(GL_FOG_DENSITY, Density);
}
}

// DirectX 8.0
//
// В этом примере g_pDevice - это действующий
указатель
// на интерфейс IDirect3DDevice8.
//
void SetupPixelFog(DWORD Color, DWORD Mode)
{
float Start = 0.5f, // для линейного тумана
End = 0.8f,
Density = 0.66; // для экспоненциального

// разрешаем туман
g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);

// устанавливаем цвет тумана
g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);

// устанавливаем параметры
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));
}
}

Как видишь, все довольно просто, но не все
так хорошо как кажется на первый взгляд. Во-первых,
pixel fog выглядит довольно убого и вряд ли
намного приукрасит твой движок, а во-вторых,
при расчетах pixel fog'а используются значения
z-буфера, которые есть не что иное, как длина
перпендикуляра опущенного из
соответствующей точки 3D-сцены на плоскость
проекции, хотя на самом деле, очевидно, цвет
тумана зависит от расстояния между
фрагментом и глазом наблюдателя. В восьмом
DirectX это было учтено, и система
автоматически использует глазо-релевантные
значения глубины вместо значений z-буфера,
если имеется такая возможность.

Объемный туман

Позже, когда железо стало мощнее, кому-то
захотелось, чтобы туман заполнял не все
пространство 3D-сцены, а небольшую его часть,
например, стелился по полу какой-нибудь
комнаты. Так возникло понятие "объемный
туман" (volumetric fog), т.е. туман, заключенный в
какой-то конечный объем.

Первые попытки были очень неловкими и
напоминали, скорее, пародию, нежели,
действительно объемный туман. Так, кажется,
в третьем Tomb Raider'е можно увидеть туман,
выполненный в виде нескольких слоев
полупрозрачной текстуры расположенных
параллельно полу.

После эпохи "туманного застоя"
появился Анрыл, который и принес в массы
шикарно выглядящий объемный туман. Затем
вышел третий Квак, после которого стало
ясно, что отныне наличие объемного тумана в
FPS-играх стало не роскошью, а правилом
хорошего тона.

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

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

(Продолжение следует)

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии