Видео маппинг, видео перформансы

VJ Софт

Современная терминология 3D графики

Содержание материала

Введение

Мир 3D графики, в том числе игровой, наполнен терминами. Терминами, которые не всегда имеют единственно правильное определение. Иногда одни и те же вещи называются по-разному, и наоборот, один и тот же эффект может называться в настройках игры то "HDR", то "Bloom", то "Glow", то "Postprocessing". Большинству людей из похвальбы разработчиков о том, что они встроили в свой графический движок, непонятно, что в реальности имелось в виду.

Статья призвана помочь разобраться, что же значат некоторые из этих слов, наиболее часто употребляемые в подобных случаях. В рамках этой статьи речь пойдет далеко не обо всех терминах 3D графики, а только о тех, которые получили большее распространение в последнее время в качестве отличительных особенностей и технологий, применяемых в игровых графических движках и в качестве наименований графических настроек современных игр. Для начала, настоятельно рекомендую ознакомиться с теоретическими статьями под авторством Александра Медведева.

Если что-то в этой статье и в статьях Александра вам не понятно, то есть смысл начать с самого раннего, с "Терминологии 3D-графики" и других теоретических статей из раздела "Видеосистема" нашего сайта. Эти статьи уже несколько устарели, конечно, но основные, самые начальные и важные данные там есть. Мы же с вами поговорим о более "высокоуровневых" терминах. Основные понятия о 3D графике реального времени и устройстве графического конвейера у вас должны быть. С другой стороны, не ждите математических формул, академической точности и примеров кода - статья предназначена совсем не для этого.

Термины

Список терминов, описанных в статье:

  • Shader (Шейдер)
  • Vertex Shader (Вершинный Шейдер)
  • Pixel Shader (Пиксельный Шейдер)
  • Procedural Textures (Процедурные Текстуры)
  • Bump Mapping/Specular Bump Mapping
  • Displacement Mapping
  • Normal Mapping
  • Parallax Mapping/Offset Mapping
  • Postprocessing (Постобработка)
  • High Dynamic Range (HDR)
  • Tone Mapping
  • Bloom
  • Motion Blur
  • Depth Of Field (DOF)
  • Level Of Detail (LOD)
  • Global Illumination
  • Shader (Шейдер)
  • Vertex Shader (Вершинный Шейдер)
  • Pixel Shader (Пиксельный Шейдер)
  • Procedural Textures (Процедурные Текстуры)
  • Bump Mapping/Specular Bump Mapping
  • Displacement Mapping
  • Normal Mapping
  • Parallax Mapping/Offset Mapping
  • Postprocessing (Постобработка)
  • High Dynamic Range (HDR)
  • Tone Mapping
  • Bloom
  • Motion Blur
  • Depth Of Field (DOF)
  • Level Of Detail (LOD)
  • Global Illumination




Shader (Шейдер)

Шейдером в широком смысле называется программа для визуального определения поверхности объекта. Это может быть описание освещения, текстурирования, постобработки и т.п. Шейдеры выросли из работ Кука (Cook's shade trees) и Перлина (Perlin’s pixel stream language). Сейчас наиболее известны шейдеры RenderMan Shading Language. Программируемые шейдеры были впервые представлены в RenderMan компании Pixar, там определены несколько типов шейдеров: light source shaders, surface shaders, displacement shaders, volume shaders, imager shaders. Эти шейдеры чаще всего программно выполняются универсальными процессорами и не имеют полной аппаратной реализации. В дальнейшем, многие исследователи описывали похожие на RenderMan языки, но они уже были предназначены для аппаратного ускорения: система PixelFlow (Olano и Lastra), Quake Shader Language (применен id Software в графическом движке игры Quake III, который описывал многопроходный рендеринг), и другие. Peercy сотоварищи разработали технику для того, чтобы программы с циклами и условиями выполнять на традиционных аппаратных архитектурах при помощи нескольких проходов рендеринга. Шейдеры RenderMan разбивались на несколько проходов, которые комбинировались во фреймбуфере. Позднее появились языки, которые мы видим аппаратно ускоренными в DirectX и OpenGL. Так шейдеры были адаптированы для графических приложений реального времени.

Видеочипы раннего времени не были программируемы и исполняли только заранее запрограммированные действия (fixed-function), например, алгоритм освещения был жестко зафиксирован в железе, и нельзя было ничего изменить. Затем, компании-производители видеочипов постепенно ввели в свои чипы элементы программируемости, сначала это были очень слабые возможности (NV10, известный как NVIDIA GeForce 256, уже был способен на некоторые примитивные программы), которые не получили программной поддержки в Microsoft DirectX API, но со временем возможности постоянно расширялись. Следующий шаг был за и NV20 (GeForce 3) и NV2A (видеочип, примененный в игровой консоли Microsoft Xbox), которые стали первыми чипами с аппаратной поддержкой шейдеров DirectX API. Версия Shader Model 1.0/1.1, появившаяся в DirectX 8, была сильно ограничена, каждый шейдер (особенно это относится к пиксельным) мог быть сравнительно малой длины и сочетать весьма ограниченный набор команд. В дальнейшем, Shader Model 1 (SM1 для краткости) была улучшена с пиксельными шейдерами версии 1.4 (ATI R200), которые предлагали большую гибкость, но также имели слишком ограниченные возможности. Шейдеры того времени писались на так называемом assembly shader language, который близок к ассемблеру для универсальных процессоров. Его низкий уровень доставляет определенные сложности для понимания кода и программирования, особенно, когда код программы большой, ведь он далек от элегантности и структурированности современных языков программирования.

Версия Shader Model 2.0 (SM2), появившись в DirectX 9 (что было поддержано видеочипом ATI R300, ставшим первым GPU с поддержкой шейдерной модели версии 2.0), серьезно расширила возможности шейдеров реального времени, предложив более длинные и сложные шейдеры и заметно расширившийся набор команд. Была добавлена возможность расчетов с плавающей запятой в пиксельных шейдерах, что также стало важнейшим улучшением. DirectX 9, в лице возможностей SM2, также привнес и язык шейдеров высокого уровня - high-level shader language (HLSL), весьма похожий на язык Си. И эффективный компилятор, переводящий HLSL программы в низкоуровневый код, "понятный" для аппаратных средств. Причем, доступно несколько профилей, предназначенных для разных аппаратных архитектур. Теперь, разработчик может писать один код HLSL шейдера и компилировать его при помощи DirectX в оптимальную программу, для установленного у пользователя видеочипа. После этого выходили чипы от NVIDIA, NV30 и NV40, которые улучшили возможности аппаратных шейдеров еще на шаг, добавив еще более длинные шейдеры, возможности динамических переходов в вершинных и пиксельных шейдерах, возможность выборки текстур из вершинных шейдеров и др. С тех пор пока качественных изменений не было, они ожидаются ближе к концу 2006 года в DirectX 10...

В целом, шейдеры добавили к графическому конвейеру множество новых возможностей по трансформации и освещению вершин и индивидуальной обработке пикселей так, как этого хотят разработчики каждого конкретного приложения. И все-таки, возможности аппаратных шейдеров до сих пор не раскрыты в приложениях полностью, а ведь с увеличением их возможностей в каждом новом поколении "железа", мы скоро увидим уровень тех самых шейдеров RenderMan, которые когда-то казались недостижимыми для игровых видеоускорителей. Пока в шейдерных моделях реального времени, поддерживаемых на сегодняшний день аппаратными видеоускорителями, определено лишь два типа шейдеров: Vertex Shader и Pixel Shader (в определении DirectX 9 API). В будущем DirectX 10 к ним обещает добавиться еще и Geometry Shader.


 

Vertex Shader (Вершинный Шейдер)

Вершинные шейдеры - это программы, выполняемые видеочипами, которые производят математические операции с вершинами (vertex, из них состоят 3D объекты в играх), иначе говоря, они предоставляют возможность выполнять программируемые алгоритмы по изменению параметров вершин и их освещению (T&L - Transform & Lighting). Каждая вершина определяется несколькими переменными, например, положение вершины в 3D пространстве определяется координатами: x, y и z. Вершины также могут быть описаны характеристиками цвета, текстурными координатами и т.п. Вершинные шейдеры, в зависимости от алгоритмов, изменяют эти данные в процессе своей работы, например, вычисляя и записывая новые координаты и/или цвет. То есть, входные данные вершинного шейдера - данные об одной вершине геометрической модели, которая в данный момент обрабатывается. Обычно это координаты в пространстве, нормаль, компоненты цвета и текстурные координаты. Результирующие данные выполняемой программы служат входными для дальнейшей части конвейера, растеризатор делает линейную интерполяцию входных данных для поверхности треугольника и для каждого пикселя исполняет соответствующий пиксельный шейдер. Очень простой и грубый (но наглядный, надеюсь) пример: вершинный шейдер позволяет взять 3D объект сферы и вершинным шейдером сделать из него зеленый куб :).

До появления видеочипа NV20 у разработчиков было два пути, либо использовать собственные программы и алгоритмы, изменяющие параметры вершин, но тогда все расчеты делал бы CPU (software T&L), либо полагаться на фиксированные алгоритмы в видеочипах, с поддержкой аппаратной трансформации и освещения (hardware T&L). Первая же шейдерная модель DirectX означала большой шаг вперед от фиксированных функций по трансформации и освещению вершин к полностью программируемым алгоритмам. Стало возможным, например, выполнять алгоритм скининга полностью на видеочипах, а до этого единственной возможностью было их исполнение на универсальных центральных процессорах. Теперь, с сильно улучшенными со времен упомянутого чипа NVIDIA возможностями, с вершинами при помощи вершинных шейдеров можно делать уже очень многое (кроме их создания, разве что)...

Примеры того, как и где применяются вершинные шейдеры:

  • Скининг (skinning). Matrix pallete skinning для скелетной анимации персонажей с большим количеством "костей". Примеры вы видите практически во всех играх. Но приведу один скриншот из Call of Duty 2, над вершинами каждого из персонажей поработал алгоритм скининга. Причем, с шейдерами версии 3.0 сделать скининг стало заметно проще, для шейдеров версии 1.1 нужно было писать несколько шейдеров для каждого вида скининга (с определенным количеством "костей").
    Call of Duty 2
  • Деформация объектов. Как самый явный и эффектный пример - создание реалистичных волн в динамике. Примеры подобных решений наблюдаются в играх F.E.A.R. и Pacific Fighters, причем в последнем сделана, пожалуй, самая реалистичная вода реального времени, применяются вершинные шейдеры 3.0 и доступ к текстурам из них, настоящий Displacement Mapping в дополнение к Bump Mapping:
    F.E.A.R.   Pacific Fighters
    Конечно, похожий эффект волн в динамике, как в F.E.A.R., может быть запрограммирован и на пиксельном уровне (Morrowind), но в данном случае речь об изменении реальной геометрии, что всегда реалистичнее выглядит.
  • Анимация объектов. Например, травы и деревьев в одном из первых применений - 3DMark 2001 SE, алгоритм анимации был значительно улучшен в следующем 3DMark 03:
    3DMark 2001 SE   3DMark 03
  • Toon shading/Cel shading. Используется в некоторых играх для создания специального эффекта "мультяшного" изображения:
    TMNT   XIII
  • Имитация ткани (Cloth Simulation) - для имитации поведения подобных ткани материалов, которой очень не хватает в большинстве игр. Наиболее просто понять, о чем речь, по такой картинке:
    Cloth Demo

 


 

Pixel Shader (Пиксельный Шейдер)

Пиксельные шейдеры - это программы, выполняемые видеочипом во время растеризации для каждого пикселя изображения, они производят выборку из текстур и/или математические операции над цветом и значением глубины (Z-buffer) пикселей. Все инструкции пиксельного шейдера выполняются попиксельно, после того, как операции с трансформированием и освещением геометрии завершены. Пиксельный шейдер в итоге своей работы выдает конечное значение цвета пикселя и Z-значение для последующего этапа графического конвейера, блендинга. Наиболее простой пример пиксельного шейдера, который можно привести: банальное мультитекстурирование, просто смешение двух текстур (diffuse и lightmap, например) и наложение результата вычисления на пиксель.

До появления видеочипов с аппаратной поддержкой пиксельных шейдеров, у разработчиков были лишь возможности по обычному мультитекстурированию и альфа-блендингу, что существенно ограничивало возможности по многим визуальным эффектам и не позволяло делать многое из того, что сейчас доступно. И если с геометрией еще что-то можно было делать программно, то с пикселями - нет. Ранние версии DirectX (до 7.0 включительно) всегда выполняли все расчеты повершинно и предлагали крайне ограниченную функциональность по попиксельному освещению (вспоминаем EMBM - environment bump mapping и DOT3) в последних версиях. Пиксельные шейдеры сделали возможным освещение любых поверхностей попиксельно, используя запрограммированные разработчиками материалы. Появившиеся в NV20 пиксельные шейдеры версии 1.1 (в понимании DirectX) уже могли не только делать мультитекстурирование, но и многое другое, хотя большинство игр, использующих SM1, просто использовали традиционное мультитекстурирование на большинстве поверхностей, выполняя более сложные пиксельные шейдеры лишь на части поверхностей, для создания разнообразных спецэффектов (все знают, что вода до сих пор является наиболее частым примером использования пиксельных шейдеров в играх). Сейчас, после появления SM3 и поддерживающих их видеочипов, возможности пиксельных шейдеров доросли уже до того, чтобы с их помощью делать даже трассировку лучей (raytracing), пусть пока с некоторыми ограничениями.

Примеры применения пиксельных шейдеров:

  • Мультитекстурирование. Несколько слоев текстур (colormap, detailmap, lightmap и т.д.). Используется вообще во всех играх.
    Half-Life 2   Serious Sam 2
  • Попиксельное освещение. Bump mapping. Normal mapping. С недавних пор применяется практически везде.
    TES4   Far Cry
  • Постобработка кадра. Все эти эффекты Bloom, Depth of Field и Motion Blur...
    F.E.A.R.   TRON 2.0
  • Процедурные текстуры, такие, как текстура дерева или мрамора. Примеры:
    Lightwave   3DMark 03

 


 

Bump Mapping/Specular Bump Mapping

Бампмаппинг - это техника симуляции неровностей (или моделирования микрорельефа, как больше нравится) на плоской поверхности без больших вычислительных затрат и изменения геометрии. Для каждого пикселя поверхности выполняется вычисление освещения, исходя из значений в специальной карте высот, называемой bumpmap. Это обычно 8-битная черно-белая текстура и значения цвета текстуры не накладываются как обычные текстуры, а используются для описания неровности поверхности. Цвет каждого текселя определяет высоту соответствующей точки рельефа, большие значения означают большую высоту над исходной поверхностью, а меньшие, соответственно, меньшую. Или наоборот.

Степень освещенности точки зависит от угла падения лучей света. Чем меньше угол между нормалью и лучом света, тем больше освещенность точки поверхности. То есть, если взять ровную поверхность, то нормали в каждой ее точке будут одинаковыми и освещенность также будет одинаковой. А если поверхность неровная (собственно, практически все поверхности в реальности), то нормали в каждой точке будут разными. И освещенность разная, в одной точке она будет больше, в другой - меньше. Отсюда и принцип бампмаппинга - для моделирования неровностей для разных точек полигона задаются нормали к поверхности, которые учитываются при вычислении попиксельного освещения. В результате получается более натуральное изображение поверхности, бампмаппинг дает поверхности большую детализацию, такую, как неровности на кирпиче, поры на коже и т.п., без увеличения геометрической сложности модели, так как расчеты ведутся на пиксельном уровне. Причем, при изменении положения источника света освещение этих неровностей правильно изменяется.

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

Для продолжения необходимо напомнить о составляющих освещения. Цвет точки поверхности рассчитывается как сумма ambient, diffuse и specular составляющих от всех источников света в сцене (в идеале от всех, зачастую многими пренебрегают). Вклад в это значение от каждого источника света зависит от расстояния между источником света и точкой на поверхности.

Составляющие освещения:

Lighting А теперь добавим к этому бампмаппинг:

Bumpmapping

Равномерная (ambient) составляющая освещения - аппроксимация глобального освещения, "начальное" освещение для каждой точки сцены, при котором все точки освещаются одинаково и освещенность не зависит от других факторов.
Диффузная (diffuse) составляющая освещения зависит от положения источника освещения и от нормали поверхности. Эта составляющая освещения разная для каждой вершины объекта, что придает им объем. Свет уже не заполняет поверхность одинаковым оттенком.
Бликовая (specular) составляющая освещения проявляется в бликах отражения лучей света от поверхности. Для ее расчета, помимо вектора положения источника света и нормали, используются еще два вектора: вектор направления взгляда и вектор отражения. Specular модель освещения впервые предложил Фонг (Phong Bui-Tong). Эти блики существенно увеличивают реалистичность изображения, ведь редкие реальные поверхности не отражают свет, поэтому specular составляющая очень важна. Особенно в движении, потому что по бликам сразу видно изменение положения камеры или самого объекта. В дальнейшем, исследователи придумывали иные способы вычисления этой составляющей, более сложные (Blinn, Cook-Torrance, Ward), учитывающие распределение энергии света, его поглощение материалами и рассеивания в виде диффузной составляющей.

Итак, Specular Bump Mapping получается таким образом:

Bumpmapping

И посмотрим то же самое на примере игры, Call of Duty 2:

Call of Duty 2
Первый фрагмент картинки - рендеринг без бампмаппинга (нормалмаппинга) вообще, второй (справа-сверху) - бампмаппинг без бликовой составляющей, третий - с бликовой составляющей нормальной величины, какая используется в игре, и последний, справа-снизу - с максимально возможным значением specular составляющей.

Что касается первого аппаратного применения, то некоторые виды бампмаппинга (Emboss Bump Mapping) стали использовать еще во времена видеокарт на базе чипов NVIDIA Riva TNT, однако техники того времени были крайне примитивны и широкого применения не получили. Следующим известным типом стал Environment Mapped Bump Mapping (EMBM), но аппаратной его поддержкой в DirectX в то время обладали только видеокарты Matrox, и опять применение было сильно ограничено. Затем появился Dot3 Bump Mapping и видеочипы того времени (GeForce 256 и GeForce 2) требовали три прохода для того, чтобы полностью выполнить такой математический алгоритм, так как они ограничены двумя одновременно используемыми текстурами. Начиная с NV20 (GeForce3), появилась возможность делать то же самое за один проход при помощи пиксельных шейдеров. Дальше - больше. Стали применять более эффективные техники, такие как Normal Mapping.

Примеры применения бампмаппинга в играх:

Evolva   RSC


 

Displacement Mapping

Наложение карт смещения (Displacement Mapping) является методом добавления деталей к трехмерным объектам. В отличие от бампмаппинга и других попиксельных методов, когда картами высот правильно моделируется только освещенность точки, но не изменяется ее положение в пространстве, что дает лишь иллюзию увеличения сложности поверхности, карты смещения позволяют получить настоящие сложные 3D объекты из вершин и полигонов, без ограничений, присущих попиксельным методам. Этот метод изменяет положение вершин треугольников, сдвигая их по нормали на величину, исходя из значений в картах смещения. Карта смещения (displacement map) - это обычно черно-белая текстура, и значения в ней используются для определения высоты каждой точки поверхности объекта (значения могут храниться как 8-битные или 16-битные числа), схоже с bumpmap. Часто карты смещения используются (в этом случае они называются и картами высот) для создания земной поверхности с холмами и впадинами. Так как рельеф местности описывается двухмерной картой смещения, его относительно легко деформировать при необходимости, так как это потребует всего лишь модификации карты смещения и рендеринга на ее основе поверхности в следующем кадре.

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

Displacement Mapping

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

Displacement Mapping
Количество треугольников, созданных при тесселяции, должно быть достаточно большим для того, чтобы передать все детали, задаваемые картой смещений. Иногда дополнительные треугольники создаются автоматически, используя N-патчи или другие методы. Карты смещения лучше использовать совместно с бампмаппингом для создания мелких деталей, где достаточно правильного попиксельного освещения.

Наложение карт смещения впервые получило поддержку в DirectX 9.0. Это была первая версия данного API, которая поддержала технику Displacement Mapping. В DX9 поддерживается два типа наложения карт смещения, filtered и presampled. Первый метод был поддержан забытым уже видеочипом MATROX Parhelia, а второй - ATI RADEON 9700. Filtered метод отличается тем, что позволяет использовать мип-уровни для карт смещения и применять для них трилинейную фильтрацию. В таком методе мип-уровень карты смещения выбирается для каждой вершины на основе расстояния от вершины до камеры, то есть уровень детализации выбирается автоматически. Таким образом достигается почти равномерное разбиение сцены, когда треугольники имеют примерно одинаковый размер.

Наложение карт смещения можно по существу считать методом сжатия геометрии, использование карт смещения снижает объем памяти, требуемый для определенной детализации 3D модели. Громоздкие геометрические данные замещаются простыми двухмерными текстурами смещения, обычно 8-битными или 16-битными. Это снижает требования к объему памяти и пропускной способности, необходимой для доставки геометрических данных к видеочипу, а эти ограничения являются одними из главных для сегодняшних систем. Или же, при равных требованиях к пропускной способности и объему памяти, наложение карт смещения позволяет использовать намного более сложные геометрически 3D модели. Применение моделей значительно меньшей сложности, когда вместо десятков или сотен тысяч треугольников используют единицы тысяч, позволяет еще и ускорить их анимацию. Или же улучшить, применив более сложные комплексные алгоритмы и техники, вроде имитации тканей (cloth simulation).

Другое преимущество в том, что применение карт смещения превращает сложные полигональные трехмерные сетки в несколько двухмерных текстур, которые проще поддаются обработке. Например, для организации Level of Detail можно использовать обычный мип-маппинг для наложения карт смещения. Также, вместо сравнительно сложных алгоритмов сжатия трехмерных сеток можно применять привычные методы сжатия текстур, даже JPEG-подобные. А для процедурного создания 3D объектов можно использовать обычные алгоритмы для двухмерных текстур.

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

В качестве примера из реальных игр приведу игру, в которой используется выборка текстур из вершинного шейдера, возможность, появившаяся в видеочипах NVIDIA NV40 и шейдерной модели 3.0. Вершинное текстурирование можно применить для полностью выполняемого видеочипом простого метода наложения карт смещения, без тесселяции (разбиения на большее количество треугольников). Применение такому алгоритму ограничено, они имеют смысл, только если карты будут динамическими, то есть, будут изменяться в процессе. Например, это рендеринг больших водных поверхностей, что и сделано в игре Pacific Fighters:

DM off   DM on


 

Normal Mapping

Нормалмаппинг - это улучшенная разновидность техники бампмаппинга, описанной ранее, расширенная ее версия. Бампмаппинг был разработан Блинном (Blinn) еще в 1978 году, нормали поверхности при этом методе наложения рельефа изменяются на основе информации из карт высот (bump map). В то время как бампмаппинг всего лишь изменяет существующую нормаль для точек поверхности, нормалмаппинг полностью заменяет нормали при помощи выборки их значений из специально подготовленной карты нормалей (normal map). Эти карты обычно являются текстурами с сохраненными в них заранее просчитанными значениями нормалей, представленными в виде компонент цвета RGB (впрочем, есть и специальные форматы для карт нормалей, в том числе со сжатием), в отличие от 8-битных черно-белых карт высот в бампмаппинге.

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


Normal Mapping

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

Карты нормалей обычно создаются на основе двух версий модели, низко- и высокополигональной. Низкополигональная модель состоит из минимума геометрии, основных форм объекта, а высокополигональная содержит все необходимое для максимальной детализации. Затем, при помощи специальных утилит они сравниваются друг с другом, разница рассчитывается и сохраняется в текстуре, называемой картой нормалей. При ее создании дополнительно можно использовать и bump map для очень мелких деталей, которые даже в высокополигональной модели не смоделировать (поры кожи, другие мелкие углубления).

Карты нормалей изначально были представлены в виде обычных RGB текстур, где компоненты цвета R, G и B (от 0 до 1) интерпретируются как координаты X, Y и Z. Каждый тексель в карте нормалей представлен как нормаль точки поверхности. Карты нормалей могут быть двух видов: с координатами в model space (общей системе координат) или tangent space (термин на русском - "касательное пространство", локальная система координат треугольника). Чаще применяется второй вариант. Когда карты нормалей представлены в model space, то они должны иметь три компоненты, так как могут быть представлены все направления, а когда в локальной системе координат tangent space, то можно обойтись двумя компонентами, а третью получить в пиксельном шейдере.


Bump Maps - Normal Maps

Современные приложения реального времени до сих пор сильно проигрывают пререндеренной анимации по качеству изображения, это касается, прежде всего, качества освещения и геометрической сложности сцен. Количество вершин и треугольников, рассчитываемых в реальном времени, ограничено. Поэтому очень важны методы, позволяющие снизить количество геометрии. До нормалмаппинга были разработаны несколько таких методов, но низкополигональные модели даже с бампмаппингом получаются заметно хуже более сложных моделей. Нормалмаппинг хоть и имеет несколько недостатков (самый явный - так как модель остается низкополигональной, это легко видно по ее угловатым границам), но итоговое качество рендеринга заметно улучшается, оставляя геометрическую сложность моделей низкой. В последнее время хорошо видно увеличение популярности данной методики и использование ее во всех популярных игровых движках. "Виной" этому - комбинация отличного результирующего качества и одновременное снижение требований к геометрической сложности моделей. Техника нормалмаппинга сейчас применяется почти повсеместно, все новые игры используют ее максимально широко. Вот лишь краткий список известных ПК игр с использованием нормалмаппинга: Far Cry, Doom 3, Half-Life 2, Call of Duty 2, F.E.A.R., Quake 4. Все они выглядят намного лучше, чем игры прошлого, в том числе из-за применения карт нормалей.


Quake 4   UT2007

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


Parallax Mapping/Offset Mapping

После нормалмаппинга, разработанного еще в 1984 году, последовало рельефное текстурирование (Relief Texture Mapping), представленное Olivera и Bishop в 1999 году. Это метод для наложения текстур, основанный на информации о глубине. Метод не нашел применения в играх, но его идея способствовала продолжению работ над параллаксмаппингом и его улучшении. Kaneko в 2001 представил parallax mapping, который стал первым эффективным методом для попиксельного отображения эффекта параллакса. В 2004 году Welsh продемонстрировал применение параллаксмаппинга на программируемых видеочипах.

У этого метода, пожалуй, больше всего различных названий. Перечислю те, которые встречал: Parallax Mapping, Offset Mapping, Virtual Displacement Mapping, Per-Pixel Displacement Mapping. В статье для краткости применяется первое название.
Параллаксмаппинг - это еще одна альтернатива техникам бампмаппинга и нормалмаппинга, которая дает еще большее представление о деталях поверхности, более натуралистичное отображение 3D поверхностей, также без слишком больших потерь производительности. Это техника похожа одновременно на наложение карт смещения и нормалмаппинг, это нечто среднее между ними. Метод тоже предназначен для отображения большего количества деталей поверхности, чем есть в исходной геометрической модели. Он похож на нормалмаппинг, но отличие в том, что метод искажает наложение текстуры, изменяя текстурные координаты так, что когда вы смотрите на поверхность под разными углами, она выглядит выпуклой, хотя в реальности поверхность плоская и не изменяется. Иными словами, Parallax Mapping - это техника аппроксимации эффекта смещения точек поверхности в зависимости от изменения точки зрения.

Техника сдвигает текстурные координаты (поэтому технику иногда называют offset mapping) так, чтобы поверхность выглядела более объемной. Идея метода состоит в том, чтобы возвращать текстурные координаты той точки, где видовой вектор пересекает поверхность. Это требует просчета лучей (рейтрейсинг) для карты высот, но если она не имеет слишком сильно изменяющихся значений ("гладкая" или "плавная"), то можно обойтись аппроксимацией. Такой метод хорош для поверхностей с плавно изменяющимися высотами, без просчета пересечений и больших значений смещения. Подобный простой алгоритм отличается от нормалмаппинга всего тремя инструкциями пиксельного шейдера: две математические инструкции и одна дополнительная выборка из текстуры. После того, как вычислена новая текстурная координата, она используется дальше для чтения других текстурных слоев: базовой текстуры, карты нормалей и т.п. Такой метод параллаксмаппинга на современных видеочипах почти также эффективен, как обычное наложение текстур, а его результатом является более реалистичной отображение поверхности, по сравнению с простым нормалмаппингом.


Parallax Mapping

Но использование обычного параллаксмаппинга ограничено картами высот с небольшой разницей значений. "Крутые" неровности обрабатываются алгоритмом некорректно, появляются различные артефакты, "плавание" текстур и пр. Было разработано несколько модифицированных методов для улучшения техники параллаксмаппинга. Несколько исследователей (Yerex, Donnelly, Tatarchuk, Policarpo) описали новые методы, улучшающие начальный алгоритм. Почти все идеи основаны на трассировке лучей в пиксельном шейдере для определения пересечений деталей поверхностей друг другом. Модифицированные методики получили несколько разных названий: Parallax Mapping with Occlusion, Parallax Mapping with Distance Functions, Parallax Occlusion Mapping. Для краткости будем их все называть Parallax Occlusion Mapping.

Методы Parallax Occlusion Mapping включают еще и трассировку лучей для определения высот и учета видимости текселей. Ведь при взгляде под углом к поверхности тексели загораживают друг друга, и, учитывая это, можно добавить к эффекту параллакса больше глубины. Получаемое изображение становится реалистичнее и такие улучшенные методы можно применять для более глубокого рельефа, он отлично подходит для изображения кирпичных и каменных стен, мостовой и пр. Нужно особенно отметить, что главное отличие Parallax Mapping от Displacement Mapping в том, что расчеты все попиксельные, а не повершинные. Именно поэтому метод имеет названия вроде Virtual Displacement Mapping и Per-Pixel Displacement Mapping. Посмотрите на картинку, трудно поверить, но камни мостовой тут - всего лишь попиксельный эффект:

Parallax Mapping

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

Также, дополнительное преимущество в том, что карты высот могут динамически изменяться (поверхность воды с волнами, дырки от пуль в стенах и многое другое). В недостатках метода - отсутствие геометрически правильных силуэтов (краев объекта), ведь алгоритм попиксельный и не является настоящим displacement mapping. Зато он экономит производительность в виде снижения нагрузки на трансформацию, освещение и анимацию геометрии. Экономит видеопамять, необходимую для хранения больших объемов геометрических данных. В плюсах у техники и относительно простая интеграция в существующие приложения и использование в процессе работы привычных утилит, применяемых для нормалмаппинга.

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


F.E.A.R.   TES4


 

Postprocessing (Постобработка)

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

Простой пример из фотографии: вы сфотографировали красивое озеро с зеленью при ясной погоде. Небо получается очень ярким, а деревья - слишком темными. Вы загружаете фотографию в графический редактор и начинаете изменять яркость, контраст и другие параметры для участков изображения или для всей картинки. Но вы уже не имеете возможности изменить настройки фотоаппарата, вы делаете обработку готового изображения. Это и есть постобработка. Или другой пример: выделение заднего плана в портретной фотографии и применение blur фильтра к этой области для эффекта depth of field с большей глубиной. То есть, когда вы изменяете или подправляете кадр в графическом редакторе, вы и делаете постобработку. То же самое может делаться и в игре, в реальном времени.

Существует множество разных возможностей по обработке изображения после его рендеринга. Все видели, наверное, в графических редакторах множество так называемых графических фильтров. Это как раз то, что называется постфильтрами: blur, edge detection, sharpen, noise, smooth, emboss и др. В применении к 3D рендерингу в реальном времени это делается так - вся сцена рендерится в специальную область, render target, и после основного рендеринга это изображение дополнительно обрабатывается при помощи пиксельных шейдеров и только потом выводится на экран. Из эффектов постобработки в играх чаще всего используют Bloom, Motion Blur, Depth Of Field. Существует и множество других постэффектов: noise, flare, distortion, sepia и др.

Вот парочка ярких примеров постобработки в игровых приложениях:


Xpand Rally   Silent Hill 2


 

High Dynamic Range (HDR)

High Dynamic Range (HDR) в применении к 3D графике - это рендеринг в широком динамическом диапазоне. Суть HDR заключается в описании интенсивности и цвета реальными физическими величинами. Привычной моделью описания изображения является RGB, когда все цвета представлены в виде суммы основных цветов: красного, зеленого и синего, с разной интенсивностью в виде возможных целочисленных значений от 0 до 255 для каждого, закодированных восемью битами на цвет. Отношение максимальной интенсивности к минимальной, доступной для отображения конкретной моделью или устройством, называется динамическим диапазоном. Так, динамический диапазон модели RGB составляет 256:1 или 100:1 cd/m2 (два порядка). Эта модель описания цвета и интенсивности общепринято называется Low Dynamic Range (LDR).

Возможных значений LDR для всех случаев явно недостаточно, человек способен видеть гораздо больший диапазон, особенно при малой интенсивности света, а модель RGB слишком ограничена в таких случаях (да и при больших интенсивностях тоже). Динамический диапазон зрения человека от 10-6 до 108 cd/m2, то есть 100000000000000:1 (14 порядков). Одновременно весь диапазон мы видеть не можем, но диапазон, видимый глазом в каждый момент времени, примерно равен 10000:1 (четырем порядкам). Зрение приспосабливается к значениям из другой части диапазона освещенности постепенно, при помощи так называемой адаптации, которую легко описать ситуацией с выключением света в комнате в темное время суток - сначала глаза видят очень мало, но со временем адаптируются к изменившимся условиям освещения и видят уже намного больше. То же самое случается и при обратной смене темной среды на светлую.

Итак, динамического диапазона модели описания RGB недостаточно для представления изображений, которые человек способен видеть в реальности, эта модель значительно уменьшает возможные значения интенсивности света в верхней и нижней части диапазона. Самый распространенный пример, приводимый в материалах по HDR, - изображение затемненного помещения с окном на яркую улицу в солнечный день. С RGB моделью можно получить или нормальное отображение того, что находится за окном, или только того, что внутри помещения. Значения больше 100 cd/m 2 в LDR вообще обрезаются, это является причиной тому, что в 3D рендеринге трудно правильно отображать яркие источники света, направленные прямо в камеру.


Debevec

Сами устройства отображения данных пока что серьезно улучшить нельзя, а отказаться от LDR при расчетах имеет смысл, можно использовать реальные физические величины интенсивности и цвета (или линейно пропорциональные), а на монитор выводить максимум того, что он сможет. Суть представления HDR в использовании значений интенсивности и цвета в реальных физических величинах или линейно пропорциональных и в том, чтобы использовать не целые числа, а числа с плавающей точкой с большой точностью (например, 16 или 32 бита). Это снимет ограничения модели RGB, а динамический диапазон изображения серьезно увеличится. Но затем любое HDR изображение можно вывести на любом средстве отображения (том же RGB мониторе), с максимально возможным качеством для него при помощи специальных алгоритмов tone mapping.

HDR рендеринг позволяет изменять экспозицию уже после того, как мы отрендерили изображение. Дает возможность имитировать эффект адаптации человеческого зрения (перемещение из ярких открытых пространств в темные помещения и наоборот), позволяет выполнять физически правильное освещение, а также является унифицированным решением для применения эффектов постобработки (glare, flares, bloom, motion blur). Алгоритмы обработки изображения, цветокоррекцию, гамма-коррекцию, motion blur, bloom и другие методы постобработки качественней выполнять в HDR представлении.


HDR Motion Blur

В приложениях 3D рендеринга реального времени (играх, в основном) HDR рендеринг начали использовать не так давно, ведь это требует вычислений и поддержки render target в форматах с плавающей точкой, которые впервые стали доступны только на видеочипах с поддержкой DirectX 9. Обычный путь HDR рендеринга в играх таков: рендеринг сцены в буфер формата с плавающей точкой, постобработка изображения в расширенном цветовом диапазоне (изменение контраста и яркости, цветового баланса, эффекты glare и motion blur, lens flare и подобные), применение tone mapping для вывода итоговой HDR картинки на LDR устройство отображения. Иногда используются карты среды (environment maps) в HDR форматах, для статических отражений на объектах, весьма интересны применения HDR в имитации динамических преломлений и отражений, для этого также могут использоваться динамические карты в форматах с плавающей точкой. К этому можно добавить еще лайтмапы (light maps), заранее рассчитанные и сохраненные в HDR формате. Многое из перечисленного сделано, например, в Half-Life 2: Lost Coast.


Half-Life 2: Lost Coast

HDR рендеринг очень полезен для комплексной постобработки более высокого качества, по сравнению с обычными методами. Тот же bloom будет выглядеть реалистичнее при расчетах в HDR модели представления. Например, как это сделано в игре Far Cry от Crytek, там используются стандартные методы HDR рендеринга: применение bloom фильтров, представленные Kawase и tone mapping оператор Reinhard.


Far Cry

К сожалению, в некоторых случаях разработчики игр могут скрывать под названием HDR просто фильтр bloom, рассчитываемый в обычном LDR диапазоне. И хотя большая часть в том, что сейчас делают в играх с HDR рендерингом, как раз и есть bloom лучшего качества, выгода от HDR рендеринга не ограничивается одним этим постэффектом, просто его сделать легче всего.

Другие примеры применения HDR рендеринга в приложениях реального времени:


The Project   3DMark 06

 


Tone Mapping

Tone mapping - это процесс преобразования диапазона яркостей HDR к LDR диапазону, отображаемому устройством вывода, например, монитором или принтером, так как вывод HDR изображений на них потребует преобразования динамического диапазона и цветового охвата модели HDR в соответствующий динамический диапазон LDR, чаще всего модель RGB. Ведь диапазон яркости, представленный в HDR, очень широк, это несколько порядков абсолютного динамического диапазона единовременно, в одной сцене. А диапазон, который можно воспроизвести на привычных устройствах вывода (мониторах, телевизорах), составляет лишь около двух порядков динамического диапазона.

Преобразование из HDR в LDR и называется tone mapping, оно выполняется с потерями и имитирует свойства человеческого зрения. Такие алгоритмы принято называть операторами tone mapping. Операторы разделяют все значения яркости изображения на три разных типа: с темной, средней и яркой освещенностью. На основе оценки яркости средних тонов, корректируется общая освещенность, значения яркости пикселей сцены перераспределяются для того, чтобы войти в выходной диапазон, темные пиксели осветляются, а светлые затемняются. Затем, наиболее яркие пиксели изображения приводятся к диапазону устройства вывода или выходной модели представления. На следующей картинке изображено самое простое приведение HDR изображения к LDR диапазону, линейное преобразование, а к фрагменту в центре применен более сложный оператор tone mapping, работающий так, как было описано выше:


Tone Mapping

Видно, что только с применением нелинейного tone mapping можно получить максимум деталей в изображении, а если приводить HDR к LDR линейно, то многие мелочи просто теряются. Единственно правильного алгоритма tone mapping нет, существует несколько операторов, дающих хорошие результаты в разных ситуациях. Вот наглядный пример двух разных операторов tone mapping:


Tone Mapping

Совместно с HDR рендерингом, с недавнего времени tone mapping начали применять в играх. Стало возможным опционально имитировать свойства человеческого зрения: потерю остроты в темных сценах, адаптацию к новым условиям освещения при переходах от очень ярких областей к темным и наоборот, чувствительность к изменению контраста, цвета... Вот так выглядит имитация способности зрения к адаптации в игре Far Cry. Первый скриншот показывает изображение, которое видит игрок, только что повернувшийся от темного помещения к ярко освещенному открытому пространству, а второй - то же изображение через пару секунд, после адаптации.


Far Cry   Far Cry

EventCatalog.ru — всё для организации мероприятий!