• Партнер

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

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

    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-играх стало не роскошью, а правилом
    хорошего тона.

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

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

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

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