Вячеслав Егоров
GameDev.ru / Страницы / Вячеслав Егоров / Статьи / Атмосферные эффекты в играх (Crytek, перевод)

Атмосферные эффекты в играх (Crytek, перевод)

Автор:

  1. Введение
  2. Отрисовка сцены, основанная на её глубине
  3. Расчёт солнечного света
  4. Глобальный объёмный туман
  5. Объеденение цвета неба и глобального объёмного тумана
  6. Локально распределённый туман с помощью объёмов тумана
  7. Применение тумана к полупрозрачным объектам
    7.1. Глобальный туман
    7.2. Локальные объёмы тумана
  8. Мягкие частицы
  9. Другие эффекты, получающие преимущества от доступа к глубине сцены
    9.1. Облака
    9.2. Объёмное освещение
  10. Заключение
  11. Список литературы

1. Введение


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

2. Отрисовка сцены, основанная на её глубине


  Данный тип отрисовки это гибридный подход, заимствующий главную идею у метода отложенного освещения (deferred shading). Он заключается в получении глубины каждого пикселя сцены, для возможности в дальнейшем восстановить его реальную позицию в мире. Это не значит, что применение метода отложенного освещения является обязательным. К примеру, отрисовка в CryEngine2 до сих пор работает в традиционном варианте ([[ForwardShading|forward shading]]), но применяет много техник, требующих глубину сцены для различных действий, которые будут описаны в этой статье. То, что мы делаем в отличие от других подходов к отрисовке, это разделение настоящего затенения (непрозрачных) пикселей от последующего применения атмосферных эффектов, пост процессинга и т.п. Это позволяет применять довольно сложные модели, сохраняя при этом стоимость освещения относительно небольшой, так как особые возможности реализованы в отдельных шейдерах. Это уменьшает шансы столкнуться с ограничением текущих аппаратных возможностей и разрешает более широкое использование описанных далее эффектов, так как они могут работать и на старом оборудовании.
  Одна из проблем реализации данного метода отрисовки заключается в обработке полупрозрачных поверхностей. Так же как и в методе отложенного освещения, вы сталкиваетесь с тем, что вы в действительности не знаете настоящего цвета и глубины фрагмента, так как только одна пара цвета и глубины сохраняется в буфере, но [[Overdraw|overdraw]] у сцены обычно больше единицы, и потенциально не ограничен. В общем, это сводиться к проблеме порядко-независимой отрисовки ([[OIT|order independent transparency]]), для которой на данный момент не существует приемлемых решений в пользовательском оборудовании. Возможные подходы вроде Альфа-Буферов (A-Buffers) требуют больших затрат по памяти, и не программируемы. С этой точки зрения, разработчику приходиться самому решать проблемы отсутствия порядко-независимой отрисовки, в зависимости от реализуемого эффекта.
  Чтобы сделать значения глубины фрагментов доступными для целей отрисовки, есть несколько вариантов. В идеале, глубина сцены получается в результате раннего z-pass, который заполнит нужный нам буфер глубины. Разработчики видеокарт поддерживают использование этого подхода для улучшения эффективности работы раннего отсечения по глубине, которое может существенно снизить последующую стоимость обработки фрагментов. Так как наши методы отрисовки, основанные на глубине, больше глубину сцены не меняют, z-buffer может быть использован как текстура для получения доступа к значениям глубины фрагментов (хотя тут понадобиться преобразовывать значение глубины z-buffer’a из пост-проективного пространства в видовое пространство). Более удобным был бы ввод во фрагментный шейдер, автоматически предоставляемый графическим ускорителем, но из-за ограничений текущих графических АПИ, ускорителей и шейдерных моделей это, к сожалению, не возможно по причине проблем с совместимостью. Но этот вариант должен стать жизнеспособным, сохраняющим память техникой в ближайшем будущем. На данный момент нам приходиться сохранять глубину сцены в отдельной текстуре. В CryEngine2 эта текстура глубины храниться в виде линейной, нормализованной глубины (0 у камеры, и 1 у дальней плоскости отсечения) что будет важно позже, при восстановлении позиции фрагмента в мире. Формат текстуры для хранения глубины может быть или floating point или RGBA8 (float число  будет закодировано в RGBA каналы). В DX9, где нет родных шейдерных инструкций для преобразования float->RGBA и обратно, использование RGBA8 текстур хотя и сравнимо по точности с floating point текстурой, но с точки зрения скорости отрисовки неприемлемо из-за стоимости преобразований. Однако, не смотря на это, возможно, что это будет вариантом в ГЛ реализации, где отдельные производители вводят особые инструкции для кодирования. Очередная проблема рождается при использовании мультисемплинга (MSAA). В этом случае, вывод глубины приходиться делать в буфер с мультисамплингом. Читать из такого буфера нельзя, поэтому для того чтобы получить текстуру для чтения, буфер надо разрешить (resolve - так называется процесс получения обычной текстуры из текстуры с мультисемплингом). На текущий момент не имеется способа контролировать данный процесс. И в результате значения глубины на границах объектов будут смешаны, что будет заметно позже как разрывы.
  Когда мы получим глубину фрагмента из текстуры, рассчитать его мировую позицию не составит труда. Многие реализации технологии отложенного освещения используют гомогенные координаты фрагмента для преобразования из пост-проективного пространства обратно в мировое пространство. Это занимает три шейдерных инструкции (три dp4 или mul\mad инструкции) так как мы не принимаем во внимание значение .w (оно всегда равно 1.0). Однако часто имеется возможность использовать более простой вариант, например, при реализации эффекта с помощью отрисовки полноэкранных квадов. Зная мировые координаты четырёх крайних точек дальней плоскости отсечения, которые видит камера, полноэкранный квад устанавливается с использованием разницы между каждой из этих точек и позицией камеры, как входные текстурные координаты. В процессе растеризации, эти текстурные координаты будут хранить текущий вектор направления из камеры к дальней плоскости отсечения. Умножив этот вектор на значение линейной, нормализованной глубины и добавив к результату позицию камеры, мы получим позицию текущего фрагмента в мировых координатах. Это действие требует всего одну mad инструкцию, а нужный вектор направления приходит бесплатно, благодаря растеризатору.
  Множество техник, описанных далее, для различных целей используют значение глубины сцены после того как реальная геометрия была отрисована, для того чтобы найти исходную позицию фрагментов в мировых координатах.
Страницы: 1 2 3 4 Следующая »

22 октября 2007

#atmospheric crysis

2001—2018 © GameDev.ru — Разработка игр