Многослойное рельефное текстурирование: решение вопросов фильтрации и построения мягких теней

МНОГОСЛОЙНОЕ РЕЛЬЕФНОЕ ТЕКСТУРИРОВАНИЕ: РЕШЕНИЕ ВОПРОСОВ ФИЛЬТРАЦИИ И ПОСТРОЕНИЯ МЯГКИХ

ТЕНЕЙ А.А. Безгодов

Научный руководитель - к.т.н., доцент Э.В. Стародубцев

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

Введение

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

Существует большое количество методов представления деталей поверхностей, базирующихся на изображении (image-based). Как правило, это различные способы текстурирования. Для представления рельефных деталей, таких как заклепки, трещины, выбоины, решетки и т.д., используется ряд методов рельефного текстурирования (bumpmapping, BM):

1. еmboss BM;

2. Dot3 BM;

3. еnvironment BM;

4. рага11ах BM;

5. рага11ах Occlusion Mapping (POM).

Информация о высоте и/или нормали в каждой точке поверхности выбирается из двумерных текстур. В данной работе рассматривается вариант POM для деталей, которые не могут быть представлены картой высот (non-height-field details). На рис. 1 представлены примеры деталей, представимых картой высот (слева), и не представимых картой высот (справа).

Рис. 1. Детали, представимые и не представимые картой высот

Недостатком оригинального алгоритма, предложенного в [1], является невозможность использования билинейной фильтрации (linear filtering) текстур. Как следствие, при близком рассмотрении объекты не кажутся гладкими, визуально поверхность состоит из большого числа маленьких кубиков.

В данной работе решается проблема билинейной фильтрации текстур. Предложенный алгоритм основан на алгоритме, представленном в [1]. Также предлагается вариант построения мягких теней на поверхности от детальных элементов этой поверхности.

Проблема билинейной фильтрации в оригинальном алгоритме

Необходимым условием для работы алгоритма, предложенного в [1], является расположение слоев в текстуре строго по высоте: в красном канале должен находиться самый верхний слой, в зеленом - следующий по высоте слой и т.д. (см. рис. 2).

Рис. 2. Представление слоев в оригинальном алгоритме

Если используется приближенная фильтрация (nearest filtering), то карта высот имеет вид рис. 2, слева. В случае перекрытия объектов по высоте имеет место разрыв, и элементы четко разделяются. В случае билинейной фильтрации (рис. 2, справа), карта высот имеет непрерывный вид, а элементы не могут быть четко разделены, что приводит к явным дефектам изображения.

В ходе исследования проблемы рассматривались два способа борьбы с этим недостатком алгоритма.

1. Выборочная фильтрация областей текстуры, где нет разрывов. Такой подход дал неудовлетворительный результат как по качеству, так и по производительности.

2. Альтернативные способы задания слоев в текстуре. Этот подход рассматривается в данной работе и заключается в отказе от необходимости располагать слои в текстуре строго по высоте.

Описание предлагаемого алгоритма

Принцип алгоритма

Объект, представляющий элемент детализации, определяется как совокупность из двух сложных геометрических тел Т и T2 (см. рис. 3). Каждое геометрическое тело ограничивается двумя поверхностями (слоями) и размерами текстуры (на рис. 2 плоскость текстуры находится в плоскости uv), в которой хранится информация об элементе

детализации. Одно геометрическое тело ограничено поверхностями х и у. Второе геометрическое тело ограничено поверхностями г и н.

Предлагаемый алгоритм многослойного текстурирования состоит из следующих

этапов.

1. Нахождение точки пересечения луча из точки наблюдения с одним из тел. Например, луч ЕА пересекается с телом 71, а лучи ЕВ и ЕС - с телом Т2.

2. Определение текстурных координат соответствующей точки для выборки значений из диффузной текстуры и карт нормалей.

3. Определения нормали в точке пересечения.

4. Вырезка пикселей, если луч зрения не пресекает ни одно из геометрических тел.

5. Определения затенения точки. В случае, представленном на рис. 3, затененной точкой является точка В, а А и С - освещены.

6. Расчет освещения с учетом затенения по одной из известных моделей освещения, например по Блинну.

Рис. 3. Пересечения луча с поверхностью, не представимой картой высот

Представление информации о деталях поверхности

Информация о деталях поверхности выбирается из четырех текстур:

1. текстура высот. В каждом канале (Я,0,Б,Л) хранится высота соответствующего слоя;

2. текстура х-компонент нормалей для каждого соответствующего слоя;

3. текстура у-компонент нормалей для каждого соответствующего слоя;

4. цветовая текстура. Одна для всех слоев.

На рис. 4 представлена трехмерная модель, используемая в данной работе, как пример элемента детализации поверхности.

На рис. 5 слева направо, сверху вниз представлены: диффузная текстура, карта высот, карта х-компонент нормалей и карта у-компонент нормалей для элемента детализации рис. 4. Карты высот и карты нормалей представлены поканально. Так как в текстуре могут храниться значения от 0 до 1 с восьмибитной точностью, нормали хранятся в запакованном виде - каждая компонента увеличена на единицу и разделена на два. Данные текстуры можно получать на основе трехмерных моделей.

н

в А

5 А

С

Рис. 5. Пример текстур

Определение точки пересечения

Точка пересечения луча, пущенного из глаза наблюдателя, с элементом поверхности может быть найдена путем трассировки луча в пространстве текстуры (см. рис. 6). Отрезок Ж" делится на N равных частей. Последовательно перебираются все точки до тех пор, пока не будет найдена точка внутри одного из геометрических тел. Для каждой из точек на луче определяется позиция относительно карт высот. Условием попадания внутрь тела является

dx < d

dx <d

dz <d

dz <d

f

z f w

J

Рис. 6. Линейный поиск

Ниже приводится код функции линейного поиска на языке ИЬБЬ.

UV

w

void QDRM_LinearSearch(

sampler2D qdmap,

inout float3 s,

in float3 V,

out float t)

{

t = 0;

float dt = 1.0f / LINEAR_ITERS;

V.z *= -1;

V.xyz /= abs(V.z);

V.xy *= SCALE;

float dir = sign(V.z);

if (dir < 0) s.z = 1.0f;

else s.z = 0.0f;

for (int i=0; i<LINEAR_ITERS; i++) {

float3 uvz = s + V*t;

float4 qdh = tex2D(qdmap, uvz.xy);

float depth = uvz.z;

float factor = 1.0f;

if ((qdh.r < qdh.g) && (qdh.r < depth) && (depth < qdh.g)) factor = 0; if ((qdh.b < qdh.a) && (qdh.b < depth) && (depth < qdh.a)) factor = 0; t += dt * factor;

}

s = s + V*t;

}_

qdmap - текстурный 2Б-сэмплер;

V - входная переменная, вектор в пространстве текстуры из глаз наблюдателя;

s - входная и выходная переменная. Начальная и конечная точка трассировки луча, соответственно;

t - выходная переменная, параметр уравнения прямой SS\ используется для отбрасывания визуализируемых пикселей;

LINEAR_ITERS - количество итераций в линейном поиске, порядка 10-20;

SCALE - коэффициент, определяющий рельефность объекта, в диапазоне [0...1].

Бинарный поиск

Линейный поиск дает лишь грубое приближение к поверхности, для более точного отыскания точки пересечения после линейного поиска используется бинарный поиск, см. рис. 7. Отрезок B1B2 делится точкой B3 на две равные части. Если точка удовлетворяет условию (1), то для дальнейшего деления используется B3B1, в противном случае - B2B3. Операция повторяется для полученного отрезка. B2 - точка, в которой останавливается линейный поиск, B1 - предшествующая точка.

Рис. 7. Бинарный поиск

Ниже приводится код на HLSL функции бинарного поиска.

void QDRM_BinarySearch( sampler2D qdmap,

inout in

inout

float3 float3 float

float dt =

s, V, t)

1.0h / LINEAR_ITERS;

V.z

V.xyz

V.xy

/=

-1;

abs(V.z); SCALE;

float old_t = t - dt; float3 uvz_old = s + V * ( - dt ); float3 uvz_new = s;

for (int i=0; i<BINARY_ITERS; i++) {

float3 uvz_mid = float mid t =

float4 float

qdh depth

0.5h * (uvz_old + uvz_new); 0.5h * (t + old_t);

tex2D(qdmap, uvz_mid.xy); uvz_mid.z;

{

float factor = 1.0f;

if ((qdh.r < qdh.g) && (qdh.r < depth) && (depth < qdh.g)) factor = 0; if ((qdh.b < qdh.a) && (qdh.b < depth) && (depth < qdh.a)) factor = 0;

uvz_old = lerp(uvz_old, uvz_mid, factor);

uvz_new = lerp(uvz_mid, uvz_new, factor);

old_t = lerp(old_t, mid_t, factor);

t = lerp(mid_t, t, factor);

}

s = uvz_new;

J_

qdmap - текстурный 2Б-сэмплер;

V - входная переменная, вектор в пространстве текстуры из глаз наблюдателя;

s - входная и выходная переменная. Начальная и конечная точка трассировки луча, соответственно;

t - выходная переменная, параметр уравнения прямой SS\ используется для отбрасывания визуализируемых пикселей;

BINARY_ITERS - количество итераций в бинарном поиске, порядка 5-10;

SCALE - коэффициент определяющий рельефность объекта, в диапазоне [0...1].

После выполнения линейного и бинарного поиска в переменной s хранится значение текстурных координат и глубина проникновения луча под поверхность объекта.

Построение мягких теней

Эффективный приближенный метод построения мягких теней для POM был предложен в [2]. Основная идея заключается в нахождении суммы расстояний между лучом и картой высот при трассировке луча от точки пересечения с картой высот к источнику света. В данной работе метод был модифицирован и применен к случаю многослойного рельефного текстурирования.

Луч трассируется с заданным шагом от точки, найденной в ходе линейного и бинарного поиска, к источнику света. Для каждой точки определяется факт попадания в одно из геометрических тел. И, если таковое происходит, минимальное расстояние от точки до одной из ограничивающих поверхностей добавляется в общую сумму. На рис. 8 это точка А, и расстояние берется от точки А до поверхности х. Общая сумма домно-жается на весовой коэффициент и ограничивается диапазоном [0...1]. Полученное число рассматривается как коэффициент затенения.

Рис. 8. Построение мягких теней

Во избежание эффекта «расслоения» тени степень затененности делается зависимой от угла между поверхностью объекта и направлением на источник света. Ниже приводится код на ИЬБЬ функции бинарного поиска.

void QDRM_Shadow(

sampler2D qdmap,

in float3 s,

in float3 L,

out float shadow)

shadow =0;

float t = 0;

float dt = 1.0f / LINEAR_ITERS_SHADOW;

float depth_bias;

depth_bias = abs(L.z);

L.z *= -1;

L.xyz /= abs(L.z);

L.xy *= SCALE;

L.xy *= depth_bias;

for

{

float3 uvz = s - L*t;

float4 qdh = tex2D(qdmap,

float depth = uvz.z;

qdh.g)); qdh.a));

if ((qdh.r < qdh.g) && (qdh.r < depth) && (depth < qdh.g)) shadow += min(abs(depth - qdh.r),

abs(depth -

if ((qdh.b < qdh.a) && (qdh.b < depth) && (depth < qdh.a)) shadow += min(abs(depth - qdh.b),

abs(depth -

t += dt;

}

shadow = saturate(shadow * SHADOW_WEIGHT * depth_bias);

{

}

qdmap - текстурный 2Б-сэмплер;

L - входная переменная, вектор направления источника света в пространстве текстуры;

s - входная переменная. Начальная точка трассировки луча;

LINEAR_ITERS_SHADOW - количество итераций в бинарном поиске, порядка

5-10;

SCALE - коэффициент, определяющий рельефность объекта, в диапазоне [0.. .1]; SHADOW_WEIGHT - резкость тени, значение - порядка 5-10; shadow - коэффициент затенения.

Определение нормали в точке пересечения

х- и у- компоненты нормали хранятся, соответственно, в двух текстурах. Каждый канал текстуры соответствует одному из четырех слоев. Возникает задача определения нормали в точке пересечения, и как следствие - слоя, с которым пересекся луч зрения.

z-компонента определяется через х- и у- компоненты. Если пересечение произошло со слоями Y или W, то z-компонента домножается на -1.

Ниже приводится код HLSL, выполняющий расчет нормали:

float4 qd = tex2D(qdmap, s.xy);

float4 selector = float4(0,0,0,0);

float4 dists = abs(s.z - qd);

float sgn = 1;

if (dists.x <= min(dists.y, min(dists.z, dists.w)) ) { selector = float4(1,0,0,0); sgn = +1; } if (dists.y <= min(dists.x, min(dists.z, dists.w)) ) { selector = float4(0,1,0,0); sgn = -1; }

if (dists.z < = min(dists.x, min(dists.y, dists.w)) ) { selector = float4(0,0,1,0); sgn = +1; }

if (dists.w < = min(dists.x, min(dists.y, dists.z)) ) { selector = float4(0,0,0,l); sgn = -1; }

float4 nx = tex2D(sm[2], s.xy);

float4 ny = tex2D(sm[3], s.xy);

float4 c = tex2D(sm[0], s.xy);

float3 n;

n.x = dot(nx, selector)*2-1;

n.y = dot(ny, selector)*2-1;

n.z = sqrt(max(0, 1.0-dot(n.xy,n.xy))); // max() используется во избежание извлечения корня

из отрицательного числа

n.z *= sgn;

n = normalize(n);

Отбрасывание визуализируемых пикселей

Визуализация пикселей отменяется в случае, если луч зрения не пересек ни одно из тел. Отследить такой случай можно с использованием переменной 1. Если ее значение близко к 0 или 1, то пиксель отбрасывается функцией ИЬБЬ сНр().

Ниже приведен код ИЬБЬ, осуществляющий отбрасывание пикселей:

^ > 0.999) сНр(-1);

if ^ < 0.001) сНр(-1);_

Расчет освещения

Освещенность рассчитывается любым известным методом (в данной работе используется модель освещения Блинна). Результат домножается на коэффициент затенения.

Заключение

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

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

Разработанное в рамках работы приложение тестировалось на видеокартах nVidia GeForce 7800 GT и GeForce 6600 GT. Получена производительность 65-70 и 10-15 кадров в секунду соответственно. Результаты работы программы представлены в Приложении.

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

Литература

1. Oleveira M.M., Policarpo F. 2005. Relief Mapping For Non-Height-Field Surface Details.

2. N. Tatarchuk. Dynamic Parallax Occlusion Mapping with Approximate Soft Shadows. // ACM SIGGRAPH Symposium on Interactive 3D Graphics and Games. 2006.

Приложение

Обычное текстурирование

Многослойное рельефное текстурирование

Многослойное рельефное текстурирование с освещением

Многослойное рельефное текстурирование с освещением и затенением