Bump Mapping (Бамп Маппинг)
Эти методы могут совмещаться и переплетаться с другими методами наложения текстур.
Для реализации bump mapping-а используются разные типы текстур:
Карты высот, где тексели задают высоту в соответствующем месте на карте. Такие текстуры выглядят, как чёрно-белые. Чем светлее тексель, тем выше расположена соответствующая часть поверхности.
Карты нормалей, в которых хранятся нормали для соответствующих частей поверхности. Отсюда normal mapping, который является методом достижения bump mapping-а. Нормали линейным преобразованием сопоставляются с цветами. Каждая координата (x, y, z) — для соответствующего цвета (r, g, b). Относительно ровная поверхность, означает, что x и y близки к нулю, а z — к единице, поэтому в таких текстурах преобладает синий цвет с проявлением сиреневых и зелёных оттенков. Карты нормалей можно генерировать из карт высот или из сопоставления сложной геометрии с низкополигональной (polybump).
Карты смещений. Карты, задающие смещение текстурных координат для накладываемой диффузной текстуры. Поскольку текстурные координаты двумерные, то здесь каждый элемент содержит не три компоненты, а две. К тому же, может занимать под каждую компоненту до 16-ти бит. Поэтому визуально не всегда можно посмотреть на такую текстуру.
Что такое Bump Mapping (Бамп Маппинг)?
22 июля 2005 (Обновление: 15 сен 2009)
Рельефное текстурирование
Сфера без рельефной текстуры; Рельефная текстура, наложенная на изображение ниже; Сфера геометрически идентичная первой, но с наложенной рельефной текстурой. Благодаря этому меняется реакция при затенении, в результате чего эффект бугристой поверхности делает сферу похожей на апельсин.
Рельефное текстурирование — метод в компьютерной графике для придания более реалистичного и насыщенного вида поверхности объектов.
Bump mapping
Техника заключается в том, что отклонение каждого пикселя от нормали к поверхности просчитываемого объекта смотрится в карте высот (поле высот) и применяется перед обсчётом освещения (см. для примера: затенение по Фонгу).
Кроме описанной выше техники, называемой Bump mapping, существует ряд альтернатив, также позволяющих придавать рельефность поверхностям. Bump mapping более корректно переводится как «эффект бугристой поверхности», в то время как техника с названием Relief mapping, используемым в англоязычной литературе, отличается от вышеизложенной.
Normal mapping
Технология аналогична Bump mapping, но для хранения информации о рельефе используются текстуры, в которых кодируются данные не о высоте точек поверхности, а об отклонении нормалей поверхности. Для создания таких текстур обычно используются многополигональная и низкополигональная модели, на основе которых и генерируется текстура нормалей.
Parallax mapping
Основная статья: Parallax mapping
Данная технология также использует карты нормалей, но, в отличие от normal mapping, она реализует не только освещение с учётом рельефа, но и сдвигает координаты диффузной текстуры. Этим достигается наиболее полный эффект рельефа, особенно при взгляде на поверхность под углом.
Parallax occlusion mapping
Основная статья: Parallax occlusion mapping
Parallax occlusion mapping является усовершенствованной и в то же время одной из наиболее вычислительно сложных разновидностей Parallax mapping. Фактически представляет собой форму локального рейтрейсинга (трассировки лучей) в пиксельном шейдере. Трассировка лучей используется для определения высот и учёта видимости текселей. Иными словами, данный метод позволяет создавать ещё большую глубину рельефа при небольших затратах полигонов и применении сложной геометрии. Недостаток метода — невысокая детализация силуэтов и граней.
Реализовать Parallax occlusion mapping возможно в рамках функционала API DirectX 9 Shader Model 3, однако для получения оптимальной производительности видеокарта должна обеспечивать надлежащий уровень скорости исполнения ветвлений в пиксельном шейдере. На данный момент Parallax occlusion mapping используется в некоторых компьютерных играх, например, Crysis и ArmA 2. Также эта технология используется в популярном бенчмарке 3DMark Vantage.
Displacement mapping
Эта техника, в отличие от описанных выше, изменяет геометрию поверхности по заданному полю высот, обычно передающегося в вершинный шейдер через текстуру. Преимущество в том, что освещение считается обычным способом(пиксельный шейдер может быть практически любым).
См. также
- Особенности моделирования света: Рельефное текстурирование (Bump mapping)
- Современная терминология 3D-графики
Это заготовка статьи о компьютерах. Вы можете помочь проекту, исправив и дополнив её. Это примечание по возможности следует заменить более точным. |
- Методы текстурирования
- Освещение в трёхмерной графике
Wikimedia Foundation . 2010 .
Bump mapping.
Сейчас я расскажу вам о таком эффекте, как Bump Mapping. Это словосочетание хорошо известно в кругах не только разработчиков игр, но и простых геймеров. Однако, что же это такое многие так и не знают. В этой статье я постараюсь раскрыть многие аспекты этой технологии.
Итак, что же такое bump-mapping? Это технология, которая позволяет на плоской поверхности полигона моделировать микрорельеф без особых затрат на вычисления. Фактически, у нас есть карта высот, наподобие той, которая используется для моделирования ландшафтов, однако она наносится на каждый полигон по-отдельности, причем особым образом. Подобный подход и называется bump-mapping‘ом.
Сперва, необходимо выяснить, а почему мы вообще видим микронеровности на объектах в реальной жизни? Всем известно, что степень освещенности поверхности зависит от угла, под которым на него падает свет. Чем этот угол ближе к 0 (относительно нормали), тем освещенность сильнее. При увеличении этого угла степень освещенности падает (так называемый закон косинуса). Если у нас есть однородная поверхность, то есть, нет никаких неровностей, то и нормаль в каждой точке этого полигона будет одинаковой. А, следовательно, и освещенность объекта будет одинаковой. Но если поверхность неровная, то и нормаль в каждой точке разная. И, как следствие, освещение становится неровным — где-то светлее, а где-то темнее. По таким признакам наш мозг и определяет неровности на объектах. Он замечает игру светотени и сигнализирует нам о том, что эта поверхность неровная.
При использовании bump mapping мы поступаем точно также. Мы задаем в каждой точке нормаль к поверхности, которая и учитывается при вычислении освещения. Для этого нам потребуется только нормализированный вектор от источника света и немного математики.
Сразу возникает вопрос: как задать нормаль в каждой точке? А как обычно мы задаем цвет в каждой точке? Правильно: накладываем текстуру. Так вот, по счастливой случайности координаты вектора, как и цвет, кодируются тремя числами. Для цвета это R, G и B, а для вектора это X, Y и Z. А что если мы совместим координаты с цветом, то есть сопоставим R с X, G с Y, а B с Z? Фактически, цвет мы стали воспринимать как координаты вектора! Что это даёт? А то, что теперь нормаль мы можем представить как цветную точку. А из таких точек можно создать текстуру, где каждая точка — нормаль.
Cледует остановиться на одном важном моменте. Дело в том, что цвет кодируется тремя положительными числами в диапазоне [0;1]. Однако, у вектора вполне могут быть и отрицательные координаты. Для решения этой проблемы мы сделаем небольшое преобразование с координатами вектора. Допустим, у нас есть координата X нормализированного вектора. Она лежит в диапазоне [-1,1]. Нам необходимо получить ту же координату, но только в диапазоне [0;1], однако с возможностью распаковки его обратно в [-1;1]. Для этого преобразуем его по формуле X0 = X*0.5 + 0.5. Подставив любое значение диапазона [-1;1], мы получим значение в диапазоне [0;1], причем сжатие происходит равномерно, так как функция преобразования- линейная. Для того, чтобы распаковать значение, достаточно выполнить обратные действия, а именно X = (X0 — 0.5)*2. Например, вектор (0,0,1) будет закодирован как (0.5,0.5,1), то есть этот вектор будет иметь ядовито-фиолетовый цвет.
Для расчета карт нормалей существуют специальные программы. На сайте nVidia для разработчиков есть плагин к PhotoShop’у. Все они действуют по одному и тому же принципу. В них задается карта высот, которая представляет собой черно-белое изображение, на котором более светлые пятна соответствует более высоким местам. Вот пример простой карты высот и соответствующей ей карте нормалей.
Казалось бы — все. Вот тебе нормаль, вот источник света. Только считай, да любуйся красотами 🙂 Но это ещё не все! Даже если мы будем использовать подобный метод освещения для каждого полигона, результат будет некорректным. Все дело в том, что при расчете освещения мы никак не будем учитывать направление нормали самого полигона. Ведь если мы будем каким-то образом вращать полигон, то и освещенность также должна меняться. Однако, как бы мы ни меняли ориентацию полигона, нормали на карте нормалей будут направлены в одно и то же направление. То есть, освещение, в итоге, не будет зависеть от ориентации полигона. Для исправления этой ошибки необходимо повернуть каждую нормаль в карте нормалей. Но посудите сами: допустим, у нас карта нормалей состоит из 128*128=16384 нормалей, и их всех придется повернуть. Считать — не пересчитать. А давайте будем поворачивать не сами нормали, а вектор источника света! Тогда и поворачивать придется только один вектор, что, несомненно, проще.
Для того, чтобы повернуть вектор, достаточно перевести его в новую систему координат, связанную с полигоном, где нормаль будет осью Z в новой системе. Для этого достаточно умножить вектор на матрицу преобразования. Она имеет такой вид:
[Tx Ty Tz]
[Bx By Bz]
[Nx Ny Nz]
Где вектор N(x,y,z) — нормаль к полигону, B(x,y,z) — бинормаль, T(x,y,z) — tangent.
Что такое нормаль (Normal), я думаю, понятно всем. А вот что такое бинормаль (Binormal) и Tangent не совсем ясно. Это два вектора, которые перпендикулярны друг другу и одновременно перпендикулярны нормали. То есть, эти 3 вектора представляют базис новой системы координат (ее ещё называют tangent space), в которую мы и собираемся переводить вектор направления на источник света.
Но как получить B и T, если у нас есть только нормаль? Самый простой способ — использовать два векторных произведения. Вначале, берем любой вектор, неколлинеарный нормали, и находим их векторное произведение. В итоге, мы получаем вектор T. Для того, чтобы получить B, достаточно векторно умножить T на N. Вот мы и получили 3 вектора базиса, из которого составляем матрицу трансформации. Умножаем ее на вектор источника света и получаем необходимый вектор.
А далее — дело техники. Просто скалярно умножаем каждый вектор в карте нормалей на преобразованный вектор от источника и умножаем его на диффузную компоненту данной точки (на цвет, взятый из главной текстуры).
Вот и все. Весь этот алгоритм очень хорошо ложится на вершинные и пиксельные шейдеры, особенно с использованием Cg. Поэтому было бы грех не продемонстрировать его реализацию.
Все расчеты начинаются с вершинного шейдера:
struct appdata < float4 Position : POSITION; //позиция вершины float3 Normal : NORMAL; //нормаль к полигону float2 TexCoord1 : TEXCOORD0; //главные текстурные координаты float2 TexCoord2 : TEXCOORD1; //текстурные координаты bump-текстуры >; struct vfconn < float4 Position : POSITION; //in projection space float2 TexCoord1 : TEXCOORD0; //главные текстурные координаты float2 TexCoord2 : TEXCOORD1; //текстурные координаты bump-текстуры float3 LightVector : COLOR0; //вектор источника света >; vfconn main(appdata IN, uniform float4x4 ModelViewProj, uniform float3 lightpos) < vfconn OUT; //главная трансформация вершины OUT.Position = mul(ModelViewProj, IN.Position); //передаем текстурные координаты пиксельному шейдеру без изменений OUT.TexCoord1 = IN.TexCoord1; OUT.TexCoord2 = IN.TexCoord2; //рассчитываем tangent space float3 normal = IN.Normal; float3 binormal = cross(float3(1,0,0),normal); float3 tang = cross(normal,binormal); //формируем матрицу трансформации вектора источника света float3x3 t; t[0] = tang; t[1] = binormal; t[2] = normal; //находим вектор направления света и умножаем на матрицу трансформации float3 light = mul(t,normalize(lightpos - IN.Position)); //переводим в диапазон [0;1] OUT.LightVector = 0.5 * light + 0.5.xxx; return OUT; >//main
Здесь все, должно быть, понятно. Обратите внимание, что для того, чтобы вычислить вектор бинормали, я взял вектор (1,0,0), то есть параллельный оси ОХ. Этот алгоритм чаще всего используется для реализации bump-mapping’а на ландшафте с регулярной сеткой. А, так как там не может быть нормали параллельной ОХ, то и векторное произведение никогда не выродится в нуль-вектор. Также обратите внимание на второе векторное произведение. Здесь я нормаль умножал на бинормаль. Однако, если у вас возникнут проблемы с некорректностью освещения, то есть выпуклые области будут казаться вогнутыми, то просто поменяйте эти два вектора местами.
Далее работа передается пиксельному шейдеру:
struct v2f < float2 Position : POSITION; //in projection space float2 TexCoord1 : TEXCOORD0; //первая текстура float2 TexCoord2 : TEXCOORD1; //вторая текстура float3 LightVector : COLOR0; //вектор источника света >; float3 main(v2f IN, uniform sampler2D tex1, uniform sampler2D tex2) : COLOR < //читаем цвет из основной текстуры float3 Color1 = tex2D(tex1,IN.TexCoord1); //читаем нормаль из карты нормалей и переводим ее в диапазон [-1;1] float3 bumpNormal = expand(tex2D(tex2,IN.TexCoord2)); //переводим вектор источника света в диапазон [-1;1] float3 lightVector = expand(IN.LightVector); //считаем скалярное произведение между вектором источника света и нормалью float light = dot(bumpNormal,lightVector) //умножаем степень освещенности на цвет из основной текстуры return Color1*light; >
Здесь тоже не должно возникнуть проблем. Функция expand() переводит компоненты вектора из диапазона [0;1] в диапазон [-1;1]. В финальном расчете можно заменить умножение сложением, что тоже дает неплохой эффект (в принципе, кому как нравится).
Вот, пожалуй, и все. Приведенные шейдеры очень просто подстроить, как говорится, под себя. Они дают простор для творчества. Если что, обращайтесь, всегда помогу.
20 апреля 2003 (Обновление: 15 июня 2009)
12.4 Использование bump-карты при работе с материалами
Рельефное текстурирование — метод в компьютерной графике для придания более реалистичного и насыщенного вида поверхности объектов.
Bump mapping — техника заключается в том, что отклонение каждого пикселя от нормали к поверхности просчитываемого объекта смотрится в карте высот и применяется перед обсчётом освещения (см. для примера затенение по Фонгу).
Кроме описанной выше техники, называемой «Bump mapping» существует ряд альтернатив, также позволяющих придавать рельефность поверхностям. «Bump mapping» более корректно переводится как «эффект бугристой поверхности», так как в англоязычной литературе присутствует техника с названием «Relief mapping», отличающаяся от вышеизложенной.
Для примера работы данной технологии создадим новый материал и применим к нашему чайнику.
Шаг 1. Выберите пустую ячейку материала.
Шаг 2. Установите любой цвет, например, зеленоватый. После этого в свитке Maps поставьте галочку напротив строки Bump mapping, установите значение 75. Затем в качестве карты установите изображение, показанное на рис. 1.
Рисунок 1. Текстура для применения в качестве карты бамп-мэппинга.
Свиток Maps будет выглядеть следующим образом (рис. 2):
Рисунок 2. Установленная карта бапм-меппинга.
Шаг 3. Визуализируйте сцену использую стандартные настройки визуализации (рис. 3).
Рисунок 3. Визуализированное изображение.
Как видно из визуализированного изображения, на объекте появились трехмерные выделения в соответствии с картой бамп-меппинга. Основной особенностью данного метода является то, что дополнительных полигонов, как и вообще каких-либо изменений в геометрии модели не произошло. Трехмерный текст на объекте получается в результате просчета карты нормалей.