суббота, 30 апреля 2011 г.

Упрощённый пошаговый конусный метод ( конусное отображение)в рельефном моделировании-Часть 2

 

Ссылка на оригинал

http://http.developer.nvidia.com/GPUGems3/gpugems3_ch18.html

18.4.1 Вычисление упрощённого конусного метода

Как и в пошаговом конусном методе, рассматриваемый подход требует чтобы мы построили конус для каждого элемента текстуры. Каждый конус обусловлен отношением своей ширины к высоте ( см. Рисунок 18-7с). Т.к. это отношение может хранится в одном из каналов текстурной модели, оба отображения – и глубинное и конусное хранятся в альфа-динамичной текстуре. Кроме того, коническое отображение может храниться в голубом канале рельефной текстуры ( в месте с двумя первыми компонентами нормали, записанными в красном и зелёном каналах).

Для каждого обращения к элементу текстуры ti на упрощённом конусном отображении угол конуса Сi ( разворот конуса) располагается на ti таким образом, чтобы ни одна из проекций не пересекала верхнюю плоскость более одного раза, при построении проекции в Сi. На рисунке 18-7b мы можем посмотреть на вышеописанную ситуацию, изображенную с помощью лучей и конуса ( конус зелёного цвета). Заметим, что конусный метод, конусное отображение, может быть использовано для ускорения нахождения пересечения теневых лучей с приподнятыми облостями. На рисунке 18-6 мы видим отрендеренное изображение с собсвенной тенью, составленное из результатов достигнутых тремя методами пофрагментного перемещения: различными подходами к рендерингу : (a) - рельефное моделирлвание с использованием линейного поиска, (b) - конусный пошаговый метод и (c) - рельефное моделирование с использованием упрощённого пошагового метода. Заметим что получившаяся тень складывается из результатов линейного поиска и из-за результатов ранней остановки пошагового конусного метода.

clip_image002

Рис.18-6 Рендеринг изображения с тенью, с использованием различных подходов

Упрощённый метод конусов даёт возможность вектору проекции достигнуть поверхности, однако этого не происходит. Мы создали упрощённый метод конусов используя О (n^2) алгоритм описанный с помощью псевдокода на Листинге 18-1.

Идея в том, чтобы для поиска каждой точки текстуры ti провести проекцию через каждое tj например как эта проекция, которая стартует в точке (ti.texCoord.s, ti.texCoord.t, 0.0) и достигает (tj.texCoord.s, tj.texCoord.t, tj.depth). Для каждого такого луча вычисляется следующее пересечение с вершиной плоскости и эта точка используется для нахождения отношения cone_ratio(i,j). На рисунке 18-7с изображена ситуация для данной пары точек ti, tj из искомой и исходной текстуры. Итоговое значение отношения Ci 's мы получаем, вычисляя наименьшее конусное отношение для ti , оно изображено на 18-7b. Упрощённый конусный метод завершает работу после нахождения всех исходных точек текстуры.

clip_image004

Рис.18-7. Вычисление упрощённого конусного метода

Пример 18-1. Псевдокод для вычисления упрощённого конусного метода.

for each reference texel ti do

radius_cone_C(i) = 1;

source.xyz = (ti.texCoord.s, ti.texCoord.t, 0.0);

for each destination texel tj do

destination.xyz = (tj.texCoord.s, tj.texCoord.t, tj.depth);

ray.origin = destination;

ray.direction = destination - source;

(k,w) = text_cords_next_intersection(tj, ray, depth_map);

d = depth_stored_at(k,w);

if ((d - ti.depth) > 0.0) // dst has to be above the src

cone_ratio(i,j) = length(source.xy - destination.xy) /

(d - tj.depth);

if (radius_cone_C(i) > cone_ratio(i,j))

radius_cone_C(i) = cone_ratio(i,j);

Напомним, что в псевдокоде, из Листинга 18-1 так же, как и в коде из Листинга 18-2, мы фиксируем максимальное конусное отношение на 1.0

Это сделано для того, чтобы сохранить данные по конусному моделированию в целочисленных текстурах. Хотя использование текстур с плавающей точкой предоставит нам возможности для работы с большими конусными значениями, что позволит улучшить результаты « скачковых» алгоритмов, на практике же только небольшое количество точек текстуры из конусного пространства, конусного моделирования, подходят для того, чтобы принимать участие в такого рода эксперементах. Так например на рисунке 18-8с только насыщенные ( белые) точки текстуры могут претендовать на попадение в текстуру с плавающей точкой.

clip_image006

Рис. 18-8 Сравнение различных результатов конусного моделирования а так же Глубинного моделирования

В листинге 18-2 представлен колеровщик ( программа для построения теней), для генерации упрощённого конусного метода. На рисунке 18-8 представлены 3 различных вида конусного моделирования для глубинной текстуры, ассоциированной с рельефной текстурой из рисунка 18-2. На рисунке 18-8а изображен обыкновенный конусный метод

(Даммер, 2006), результаты которого хранятся в одиночном текстурном канале. На рисунке 18-8b, мы видим четырёх-направленный конусный метод, который хранит конусные отношения для четырёх важнейших направлений в различных каналах текстуры. Обратите внимание, как различные области текстуры сопоставлены с расширенными конусами на разных направлениях. Красные точки текстуры подсвечивают конусы расширяющиеся направо, в то время как зелёные – расширяющиеся налево. Голубые точки текстуры подсвечивают конусы расширяющиеся книзу, а чёрные – кверху. На рисунке 18-8c мы можем увидеть результаты упрощённого метода конусов, данные по которому хранятся в доном канале текстуры. Заметьте что точки текстуры из этого метода намного ярче точек из обычного конусного метода на рисунке 18-8а.

Листинг 18-2. Колеровщик для генерации упрощённого конусного метода.

float4 depth2relaxedcone(

in float2 TexCoord : TEXCOORD0,

in Sampler2D ReliefSampler,

in float3 Offset ) : COLOR

{

const int search_steps = 128;

float3 src = float3(TexCoord,0); // Source texel

float3 dst = src + Offset; // Destination texel

dst.z = tex2D(ReliefSampler,dst.xy).w; // Set dest. depth

float3 vec = dst - src; // Ray direction

vec /= vec.z; // Scale ray direction so that vec.z = 1.0

vec *= 1.0 - dst.z; // Scale again

float3 step_fwd = vec/search_steps; // Length of a forward step

// Search until a new point outside the surface

float3 ray_pos = dst + step_fwd;

for( int i=1; i<search_steps; i++ )

{

float current_depth = tex2D(ReliefSampler, ray_pos.xy).w;

if ( current_depth <= ray_pos.z )

ray_pos += step_fwd;

}

// Original texel depth

float src_texel_depth = tex2D(ReliefSampler,TexCoord).w;

// Compute the cone ratio

float cone_ratio = (ray_pos.z >= src_texel_depth) ? 1.0 :

length(ray_pos.xy - TexCoord) /

(src_texel_depth - ray_pos.z);

// Check for minimum value with previous pass result

float best_ratio = tex2D(ResultSampler, TexCoord).x;

if ( cone_ratio > best_ratio )

cone_ratio = best_ratio;

return float4(cone_ratio, cone_ratio, cone_ratio, cone_ratio);

}

18.4.2 Рендеринг с использованием упрощённого конусного метода.

Чтобы оттенить фрагмент объекта, проследим за проекционным лучом, который проходит через всю текстуру, используя упрощённый «прыжковый» метод конусов. Будем двигаться по проекции, пока не достигнем точки внутри рельефной плоскости. Этот процесс напоминает описанный в пункте 18.3 для обыкновенного конусного метода. На рисунке 18-9 изображена методика поиска точки пересечения трансформированной проекции и конуса. Во первых, мы вычисляем направление вектора, раскладывая его на z компоненты (ray.direction.z), после чего, соответственно рисунку 18-9, можно записать следующее:

Уравнение 1

clip_image008

Соответственно,

Уравнение 2

clip_image010

Складываем уравнения 1 и 2 и получаем:

Уравнение 3

clip_image012

Из уравнения 3 получаем точку пересечения I:

Уравнение 4

clip_image014

clip_image016

Рис.18-9. Пересечение проекции вида с конусом.

Код из Листинга 18-3 описывает функцию пересечения проекции для упрощённого пошагового конусного метода. Для наглядности, первый цикл имеет ограниченное количество шагов конусного метода. Заметим, что использование функции saturate() необходимо для вычисления величины шага. Это гарантирует, что мы остановимся на первой точке текстуры, когда луч проекции будет находиться под рельефной плоскостью. В конце данного процесса, когда проекция предположительно достигла плоскости, мы запускаем бинарный поиск для поиска координат точки пересечения. Получив эти координаты, закрасим объект, как показано на рисунке 18.2.

Листинг 18-3. Проекция пересекает Конус построенный с помощью упрощённого пошагового метода.

// Ray intersect depth map using relaxed cone stepping.

// Depth value stored in alpha channel (black at object surface)

// and relaxed cone ratio stored in blue channel.

void ray_intersect_relaxedcone(

sampler2D relief_map, // Relaxed cone map

inout float3 ray_pos, // Ray position

inout float3 ray_dir) // Ray direction

const int cone_steps = 15;

const int binary_steps = 6;

ray_dir /= ray_dir.z; // Scale ray_dir

float ray_ratio = length(ray_dir.xy);

float3 pos = ray_pos;

for( int i=0; i<cone_steps; i++)

{

float4 tex = tex2D(relief_map, pos.xy);

float cone_ratio = tex.z;

float height = saturate(tex.w – pos.z);

float d = cone_ratio*height/(ray_ratio + cone_ratio);

pos += ray_dir * d;

}

<STRONG>

<EM>// Binary search initial range and initial position</EM>

<EM>float3</EM>

</STRONG> bs_range = 0.5 * ray_dir * pos.z;

float3 bs_position = ray_pos + bs_range;

for( int i=0; i<binary_steps; i++ )

{

float4 tex = tex2D(relief_map, bs_position.xy);

bs_range *= 0.5;

if (bs_position.z < tex.w) // If outside

bs_position += bs_range; // Move forward

else

bs_position -= bs_range; // Move backward

}

Пусть f – это фрагмент который должен быть закрашен, и К – точка в которой останавливается проекция вида (это так, до того как запущен бинарный поиск), как например показано на рисунке 18-10. Если было использовано несколько шагов – то проекционный луч может остановиться до того, как достигнет поверхности. Следовательно, чтобы осуществить прохождение вектора через все недостаточно массивные структур ( см. пример на рис. 18-4а), мы используем К как конечную точку для бинарного поиска. В этом случае, если проекция не достигает поверхности, поиск начинается с точки К.

clip_image018

Рис. 18-10 Проекция вида пересекающая фрагмент, с текстурными координатами

Пусть (m, n) координаты текстуры, записанные в К и пусть dK – глубина, хранящаяся в (m, n) (см. рисунок 18-10). Бинарный поиск будет вычислять точку пересечения на отрезке от точки Н до точки К, которая соответствует координатам текстуры ((s + m)/2, (t+n)/2) до (m, n), где (s, t) – координаты текстур фрагмента f (рис.18-10). На этом отрезке величина проникновения проекции варьируется от (dK /2) до dK .Обратите внимание на то, что вообще-то, мы можем использовать точки (m, n) и (q, r) (координаты текстуры точки J, первая точка пересечения на проекции) в качестве предельов для бинарного поиска.

Однако, т.к. мы используем фиксированное число итераций по алгоритму упрощённого конусного метода, сохранение точки (q, r) требует обуславливания в коде.

Как показывает нам наш опыт, это приводит к увеличению числа регистров использованных при выполнении процедуры закрашивания фрагмента. Железо, работающее с графикой, имеет конечное число регистров и запускает столько потоков – сколько позволяет наличие свободных регистров. Чем больше потоков мы заускаем – тем большее количесвто регистров используем. Латентность ( время ожидания) , обусловленная большим количеством читаемых текстур в рельефных методах, пропадает, когда программа симулируется на мультипоточном уровне. Чем сложнее код – тем больше регистров затрагивается и тем многопоточное процесс, что в свою очередь вызывает увеличение задержки при чтении текстуры и построении изображения. Таким образом, чтобы урезать код для шэйдера, мы будем запускать бинарный поиск с Н и К в качестве пределов. Заметим, что после всего лишь 2-х итераций бинарного поиска, тот, кто воспользовался поиском потратит не многим больше, чем тот, кто взял точки J и К.

Естественно, что использование упрощённого конусного метода приводит к тем же результатам, что и обычный конусный метод. ( Рис. 18-1b). На практике же, упрощённый метод требует гораздо меньшее количество итераций, до того как начнут появляться расширяющиеся конусы. Основываясь на нашем опыте, мы можем предположить, что для достижения необходимых результатов достаточно 15 итераций.

18.5 Заключение.

Комбинация, использующая конический пошаговый метод и бинарный поиск для вычисления ограниченных полей и их пересечений уменьшает количество появившихся artifacts на изображениях сгенерированных с помощью пофрагментного моделирования. Расширяющиеся конусы достигают более эффективного расположения в пространстве засчёт использования бинарного поиска, применяемого, также, для увеличения точности. Если используется слишком мало итераций, конечное изображение будет с теми же artifacts что были замечены при пошаговом коническом моделировании (Dummer 2006).

На практике, однако, наша техника даёт лучшие результаты на том же количестве итераций или с тем же количеством текстурных данных. Это важно .в первую очередь, для новых выпусков GPU, т.к. как только качесвто вычисления и компьютерное представление объекта улучшаться – только тогда повысится пропускная способность вычисления объектов.

Упрощённый пошаговый конусный метод неразделим с рельефным моделированием, и это правильно. Рис. 18-11 показывает использование УКМ при рендеринге глубинно-связанных значений (рис. 18-11b и 18-11d) и изменении некоторых факторов (рис. 18-11c и 18-11d). Обратите внимание, что эти эффекты получены с помощью надлежайшей корректировки направлений проекционных лучей (Policarpo et al. 2005) и не связаны с изменением конусных собсвенных значений 9 высоты, ширины)

clip_image020

Рис.18-11. Изображение показывающее изменение значений глубины и фрагментарности

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

К тому же, мипмэппинг придётся выполнять вручную, брать мнимальную величину для каждой группы точек и т.п. Instead, one should compute the mipmaps manually, by conservatively taking the minimum value for each group of pixels. Альтернативным методом является использование конических методов, стратегии ближайших соседей. В этом случае когда объект виден на каком-то расстоянии, правильно выбранный цвет текстуры помогает спрятать неточности, получненные при применении отображения с высоким разрешением. Таким образом единственный недостаток блокирующий применение мипмэппинда в коническом отображении это недостатки в представлении – не всегда видны более мелкие текстуры.

18.5.1 Дальнейшее чтение.

Отображение рельефных текстур было введено Oliveira et al. 2000 с использованием двойного обращения к периоду, предшествующему деформации, вызванной традиционным текстурным отображением. Предпериод повреждения, базирующийся на глубинном отображении, вычисляется в процессоре, а затем, результаты направляются на устройство обработки графики, для конечного моделирования. В качестве введения в фрагментные процессоры Policarpo et al. (2005) выделял в первую очерель технику для произвольного полигонального вычисления ( моделирования) и показывал, как эффективно эти методы работают в GPU. Этот симбиоз был достигнут, благодаря представлению пересечения векторно-ограниченного поля в 2D текстурном пространстве.

Oliveira and Policarpo (2005) так же описывали способы рендеринга кривых силуэтов путём установки квадратичности на каждой из вершин модели. Позднее, они показали, как отрендерить детали рельефа в предшествующих приложениях, с использованием максимально агрессивног (Policarpo and Oliveira 2006a).

Так же они описали технику отображения неограниченных полей и структур на основе полигональных моделей а так же с помощью введения нового класса замен.( фальшивок). (Policarpo and Oliveira 2006b).

К тому же, Oliveira and Brauwers (2007) показали, как использовать 2D текстуры для исследования пересечения векторов с лубинными отображениями под проекцией перспективы и как использовать полученные результаты чтобы отрендерить рефракции в реальном времени, а так же изменение среды объекта и его деформацию.

Глава 18 Упрощённый пошаговый конусный метод ( конусное отображение)в рельефном моделировании –Часть 1 (Перевод)

18.1 – Введение

Присутствие геометрических деталей на поверхности объекта кардинально меняет распределение света по его поверхности. Хотя синтез реалистичных картинок требует симуляции этого распределения настолько точно, насколько возможно, на самом-то деле моделирование распределения до мельчайших деталей является непрактичным. Чтобы разобраться в этих вопросах была разработана особая техника рельефного отображения , основанная на добавлении некоторых фрагментов и деталей в произвольные полигональные модели. ( Поликарпов, 2005). Техника позволяет отрендерить скорректированные силуэты ( Оливера и Поликарпо, 2005), а так же управлять некоторыми деталями на поверхности объекта, не скорректированных по высоте.

( Поликарпов и Оливера, 2006).

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

( несводимости, ступенчитости), а так же пропускает некоторые небольшие структуры, как например на рисунке 18 – 1а.

Некоторые «скачковые» техники до сих пор используются для ускорения (поиска) узлов векторов высоты, а так же для минимизации ступенчатости функции. (Donnelly 2005, Dummer 2006, Baboud and Décoret 2006). Пошаговый метод конусов (конусное отображение) ( ПМК) ((CSM) (Dummer 2006)) предоставляет интересное решение проблемы ускорения расчёта таких узлов в большинстве случаев, а так же исключает потери приподнятых областей, используя для этого данные полученные на основе предыдущих расчётов ( конусное отображение). Однако, т.к. ПМК использует устаревший подход, вектора обычно не доходят до нужной поверхности, что даёт неверное представление о реальной структуре объекта, как например на рисунке 18-1b. Используя улучшенный ПМК, который содержит 4 различных радиуса для каждого фрагмента ( по сторонам света – север, юг, запад, восток), мы можем немного уменьшить количество данных неточностей, несовпадений. Мы называем этот подход – 4-х направленный пошаговый конусный метод (QDCSM)( 4-х направленное конусное отображение) . Его результаты показаны на фигуре 18 – 1с.

clip_image002

Рис. 18-1. 4 примера нахождения узлов приподнятых областей, основанные на map-рендеринге 256x256 текстуры

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

( конусным отображением). (CSM). Идея состоит в том чтобы заменить линейный поиск на более быстрый «скачковый» поиск, запускаемый сразу же после бинарного. В то время как ЦСМ является медленным, с трудом определяя радиусы конусов, даже не смотря на то что вектор никогда не достигнет искомой поверхности, при использовании RSC вектор достигает искомой поверхности с первого же раза. Такой метод производит вычисления по расширяющимся конусам, что существенно ускоряет сходимость метода. Как только мы узнали, что вектор достиг поверхности, мы можем сразу же применять бинарный поиск, чтобы уточнить координаты искомых узлов. Комбинация RCS и бинарного поиска существенно увеличивает качество рендеринга, так например, как мы видим на рисунке 18 – 1d. Заметим, что весь ализинг ( все неточности), замеченные ранее на фигурах а, b, с – в данный момент пропали. Т.к. РСЦ базируется на «скачковом» алгоритме, он может быть использован с другими стратегиями для решения тех же проблем ограниченных областей, таких например, как интервальное отображение ( метод интервалов). (Risser et al. 2005).

18.2 Краткий обзор рельефного моделирования.

Рельефное моделирование ( Поликарпо, 2005) симулирует появление геометрических объектов с помощью накладывания тени, штриховки, на каждый фрагмент, согласно некоторым данным о глубине и составе поверхности (материале), причём информация содержится внутри полигональной модели.

Глубинная отображение (значения точек лежат в промежутке от 0 до 1) геометрически отрисованно, в соответствии с характером полигональной поверхности. Глубинные и нормальные отображения в индивидуальной RGBa текстуре (32 бита на каждый элемент текстуры), называются текстурой рельефа (Oliveira et al. 2000).

Для получения лучших результатов мы бы рекомендовали разделять объёмные и обычные компоненты на 2 различные текстуры. Тогда сжатие текстур, их компрессия, будет работать значительно лучше, т.к. специальное «нормальное» сжатие может быть использовано независимо от сжатия объёмного, причём, с получением лучших результатов, по качеству сжатия, а так же по количеству неточностей. Так же мы получаем, в итоге, лучшие результаты по визуализации, т.к. во время вычисления рельефного отображения необходим только один канал ( по глубине, объёму) – остальная информация нужна только в конце – для подсветки, для создания освещения. На рисунке 18 -2 показаны нормальное и глубинное отображения рельефной текстуры, поперечное сечение которых показано на рисунке 18 – 3. Составление рельефного отображения и преобразование его в полигональное сделано обычным способом, с помощью присваивания пар текстурных координат вершинам (пикам) модели ( объекта) . Во время рендеринга, глубинное отображение может динамически изменяться, для достижения различных эффектов, а правильная абсорбция достигается, в свою очередь, за счёт обновления глубинного буфера.

clip_image004

Рис. 18-2 Примеры рельефной текстуры.

clip_image006

Рис.18-3 Рельефный рендеринг

Рельефный рендеринг полностью представлен в GPU и может быть фактически разделён на три шага. Для каждого фрагмента f с координатами текстур (s,t) осуществляется преобразование из пространства V в соседнее пространство из f. Затем мы находим пересечение P с оттрансформированным ( изменённым) лучом, на глубинном отображении. Пусть (k, l) будут координатами текстур каждого узла ( см. Рисунок 18-3) . Далее, воспользуемся соответствующей позицией Р, расположенной в замкнутом, закрытом пространстве и нормалью ( нормальной позицией Р) расположенной в (k, l) чтобы оттенить f. Тень может быть настроена (наложена) с помощью проверки точки пересечения светового вектора и вектора Р, причём до того как он достигнет хоть одной точки рельефа. Рисунок 18-3 показывает весь этот процесс. Обсорбция рельефного отображения, а так же других объектов, достигается всего лишь при помощи обновления з-буффера, который хранит з-координаты от Р ( к примеру в закрытом пространстве или после выделения w и дальнейшего деления на его скаляр). Этот з-буффер так же поддерживает совместное теневое (Williams 1978) и рельефное моделирования соответственно.

На самом деле, поиск точки пересечения Р может быть представлен для начала на 2Д тектсурах. Таким образом пусть (u, v) это координаты 2Д текстуры, соответствующие той точке, в которой глубина проникновения вектора видимости достигает 1.0. (Рис. 18-3). Мы вычисляем (u, v) основанные на (s, t), на изменённом векторе видимости и на скалярной величине, установленной для глубинного отображения. Далее мы производим поиск Р для упрощенного глубинного отображения по шагам от (s, t) до (u, v), и проверяем, не достиг ли вектор видимости рельефа (а он должен достичь, иначе получится что глубина видимости превышает хранимую величину), пока не окажемся в (u, v). Если мы обнаруживаем точку, где наш вектор попадает под рельеф – местонахождение пересечения Р легче найти с помощью бинарного поиска.

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

Такая ситуация отображена на рисунке 18-4a, где значение глубины хранящееся в текстурных координатах, уже на половине процесса преобразования из (s, t)в (u, v) больше чем глубинная величина в видимой точке 1, т.к. луч уже пересёк плоскость поверхности. В таком случае, бинарный поиск приводит нас в ошибочную точку Q. Чтобы минимизировать такие упущения ализинга , Policarpo et al. (2005) использовал линейный поиск, чтобы ограничить область проведения бинарного поиска. Это отображено на Рисунке 18-4b, где шаги уменьшены для достижения точки 3 под плоскостью. Впоследствии, точки 2 и 3 служат входными параметрами для бинарного поиска. Линейный поиск, сам по себе, однако, используется для ализинга присутствующих тонких, небольших структур как например на рисунке 18-1a. Этим и обуславливается предложенное некоторыми исследователями использование дополнительных, предэксперементальных данных, для избегания потерь именно таких незначительных объектов (Donnelly 2005, Dummer 2006, Baboud and Décoret 2006). Техника, представленная в этой главе была разработана на основе пошагового метода конусов Dummer-а ( конусного отображения), который подробнее описан дальше.

clip_image008

Рис. 18-4 бинарная версия линейного поиска

18.3 Пошаговый метод конусов ( конусное отображение)

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

(Dummer 2006). Метод конусов ( конусное отображение) присваивает каждому циркулярному, круговому конусу пару точек глубинной текстуры. Угол каждого конуса – максимально допустимый, при условии что конус не пересекает верхнюю границу фигуры. Изображение на рисунке 18-5 описывает случай для трёх элементов текстуры в точках, с координатами (s, t), (a, b), и (c, d), чьи конусы изображены жёлтым, голубым и зелёным цветом соответственно.

clip_image010

Рисунок 18-5 Пошаговый метод конусов ( конусное отображение)

Начиная с фигуры f, во время изменения вида ( передвижения камеры) поиск узла пересечения происходит следующим образом: узел пересечения вектора и конуса хранится в (s, t). Полученная точка 1 – в текстурных координатах (а, b). Затем вектор продлевается до пересечения с конусом (а, b) , и мы получаем таким образом точку 2, с координатами (c, d).

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

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

Более того, 3D проекция получившегося пересечения P', в замкнутом пространсве так же не верна. Эти ошибки показывают нам об искажении результатов рендеринга, как например на фигуре 18-1b и 18-1c.

18.4 Упрощённый пошаговый конусный метод ( конусное отображение).

Пошаговый конусный метод ( конусное отображение), предложенный Даммером, заменяет оба поиска, и линейный и пошаговый ( описанные Поликарповым 2005) на простой поиск, базирующийся на конусном моделировании.

Улучшение эффективности алгоритма поиска узлов приподнятых плоскостей достигается с помощью комбинирования сильных сторон вышеуказанных алгоритмов: «прыжковые качества» пошагового конусного моделирования дополнены улучшенной точностью бинарного поиска.

Т.к. для бинарного поиска требуется наличие хотя бы двух входных параметров- точки под поверхностью рельефа, и точки над поверхностью рельефа, мы можем не рассматривать, не принимать во внимание то препятствие, из-за которого конусы из конусного метода ( конусного отображения) не могут достичь искомой плоскости. В нашем новом алгоритме, кроме всего прочего, мы продляем конусы до пересечения с плоскостью, когда это возможно. Идея состоит в том, чтобы увеличить радиус конуса настолько, насколько это возможно, соблюдая одно условие: если вектор видимости проникает внутрь конуса – то он не может пересечь рельеф больше, чем один раз. Мы называем получившийся алгоритм упрощённым конусным методом (конусным отображением). На рисунке 18-7a (в следующей подсекции) сопоставляются радиусы конусов, получившихся в ходе пошагового конусного метода ( голубой) и с помощью упрощённого конусного метода ( зелёный), для заданного фрагмента плоскости. Заметим, что радиус, полученный с помощью упрощенного конусного метода имеет большую величину, что даёт возможность алгоритму сойтись в точке пересечения за меньшее количество шагов. Использование более широких конусов из упрощенного конусного метода подходит для проведения линейного поиска, и, следовательно, для нахождения искомых результатов. Т.к. луч пересекает плоскость лишь единожды, можно так же использовать быстрый и более точный бинарный поиск.

Синильный рендеринг и поверхностное рисование–Часть 1

 

Ссылка на статью оригинал:

GPU Gems - Chapter 15. Blueprint Rendering and "Sketchy Drawings"

В этой главе мы рассмотрим два способа аппаратно-ускоренного, не фотореалестичного рендеринга: синильный рендеринг и поверхностное рисование.

Структурирование и усиление видимых и закрытых особенностей архитектурных планов и технических деталей являются существенными методиками для того, чтобы визуализировать сложные составные объекты и для того, чтобы иллюстрировать позицию, схему размещения, и соотношение их компонентов. Синильный рендеринг - новая техника мультипроходного рендеринга, основанная на усилении видимых и наиболее важных невидимых ребер 3D объектов. Первоначально слово "blueprint" расшифровывалось как: фотографическая печать белым цветом на светло-синем фоне или синим цветом на белом фоне специально для копировальных карт, машинных чертежей и архитектурных планов. Синильный рендеринг представляет собой прозрачную копию объекта, обозначенного только его контуром. Он способствует легкому пониманию структуры комплексов зданий, компоновку деталей, что позволяет упростить создание архитектурных планов, промышленных чертежей и дизайнов.

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

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

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

Методы, которыми они созданы (рендеринг спрайта глубины) и то, что они берут за основу не сам объект, оба синильные и поверхностный рендеринги могут быть легко интегрированы в любую программу, где необходимо создание графики в реальном времени.

15.1 Основные принципы

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

15.1.1 Промежуточные результаты рендеринга

Мы обозначим 2D данные, полученные из 3D геометрии и рендеринга текстуры, как промежуточные результаты рендеринга. Также, мы реализуем G-буфер (Сэйто и Такахаши 1990), который сохраняет свойства геометрии в 3D geometry. (см. Также главу 9 этой книги, "Отсроченное затенение в S.T.A.L.K.E.R.," программная реализация этой идеи в реальном рендеринге.) Мы создаем буфер нормалей и z-буфер, путем рендеринга закодированных нормалей и z-значений 3D геометрии напрямую в 2D текстуру, см. Рисунок 15-1. В методе многопоточного рендеринга, мы создаем промежуточные результаты рендеринга один раз, и потом они могут использоваться в последовательности прохождений рендера. Технически, мы используем аппаратные возможности рендеринга в текстуру. Это позволяет нам рендерить значения высокой точности(цвета) и буферы высокой точности(как в текстурах).

clip_image001

Figure 15-1 Steps in Creating an Edge Map

15.1.2 Усиление ребер

Для извлечения важных видимых ребер из 3D геометрии на объектной основе, мы реализуем технику усиления ребер изображения (Ниенхаус и Дёллнер 2003). Важные видимые ребра включают в себя силуэт, грань и изогнутые ребра. Мы получаем эти ребра путем обнаружения разрывов в буфере нормалей и z-буфере. Для этих целей мы текстурируем выравненную четверть, у которой выделены края, используя текстуры и вычисляя координаты текстуры (s, t) для каждого фрагмента четверти, созданных в таком же порядке, каком они запрашивают координаты окна. Отбор соседних тикселей (пикселей текстуры) позволяет нам извлечь разрывы, как результаты значений интенсивности. Собрание значений интенсивности составляют ребра, которые мы рендерим прямо в единую текстуру, которую назовем карта ребер. Рисунок 15-2 отображает буфер нормалей, z-буфер и результаты карты ребер.

clip_image002

Рисунок 15-2 Z-буфер, буфер нормалей, и карта ребер для каждого слоя

15.1.3 Рендеринг спрайта глубины

В принципе, спрайт глубины – это 2D изображение, которое содержит дополнительное z-значение в каждом пикселе для тестирования глубины. Для наших целей, мы реализуем рендеринг спрайта глубины следующим образом:

  1. Мы рендерим выравненную, затекстурированную четверть с текстурой высокой точности, содержащую z-значения.
  2. Применяем специальный фрагмент программы построения теней(шейдер), который заменяет фрагмент z-значений в четверти, с z-значениями принятыми от текстуры. Для оптимизации мы дополнительно убираем фрагмент, если его z-значение равно 1—которое обозначает глубину дальнего отрезка плоскости. В другом случае, этот фрагмент-шейдер высчитывает RGBA значения цвета этого фрагмент.
  3. Рендеринг продолжается с обычным тестом глубины. Если фрагменты прошли тест, буфер кадров будет заполнен цветом и z-значениями спрайта глубины.

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

15.2 Синильный рендеринг

Для синильного рендеринга мы выбираем видимые и невидимые ребра 3D геометрии. Видимые ребра – это ребра, которые непосредственно видно в виртуальную камеру; невидимые – это ребра, которые закрыты плоскостью 3D геометрии; проще сказать, их не видно. Чтобы извлечь ребра, мы объединяем технику глубинной очистки (Эверитт 2001) и технику усиления ребер. Сгенерировав один раз, мы сравниваем видимые и невидимые ребра как светокопии в буфере кадров.

15.2.1 Глубинная очистка

Глубинная очистка – это техника воздействия на каждый фрагмент основы и извлечения 2D слоев из 3D геометрии в отсортированном по глубине порядке. В общем говоря, глубинная чистка последовательно очищает слои с уникальной сложностью глубины.

Фрагменты, прошедшие обычный тест глубины, определены минимальным z-значением каждого пикселя. Но мы не можем определить фрагмент, который пришел вторым (третьим и т.д), соблюдая их сложность глубины. Таким образом, нам нужен дополнительный тест глубины, извлекающий те фрагменты, номер слоя которых, соответствует данному порядковому номеру (Дифенбах 1996). Мы можем выбрать первых n слоев с помощью n проходов рендера.

Мы ссылаемся на слой с уникальной сложностью глубины, как на слой глубины и текстуру высокой точности, полученных от захвата содержимого взаимодействующего z-буфера, и назовем его карта слоя глубины. Соответственно, мы называем захваченное содержимое взаимодействующего цветного буфера с дополнительной текстурой, как цветная карта слоя. В частности, цветные карты слоя могут позднее использоваться в списке, сортированном по глубине, для сравнения конечного рендеринга (Эверитт 2001).

Псевдокод в Листинге 15-1 показывает нашу разработку глубинной чистки. Он срабатывает при установке G в 3D геометрии. Мы рендерим G несколько раз, в результате rasterizer создает F фрагментов. Цикл работы заканчивается, когда все фрагменты будут обработаны; иначе мы обрабатываем следующий слой глубины. То есть, если число проходов рендера достигло максимальной глубины сложности, то условие выполнено.

Example 15-1. Псевдокод совмещения Глубинной чистки и Улучшения Ребер для Синильногорендеринга
procedure depthPeeling(G clip_image003 3DGeometry) begin
   i=0
   do
     F clip_image003[1] rasterize(G)
     /* Подготовка теста глубины для первого прохода рендера */
     if(i==0)  begin
       for all fragment ∈ F  begin
         bool test clip_image003[2] performDepthTest(fragment)
         if(test)  begin
           fragment.depth clip_image004 z-buffer
           fragment.color clip_image004[1] color buffer
         end
         else reject fragment
       end
     end
     else begin
       /* Подготовка второго теста */
       for all fragment ∈ F  begin
         if(fragment.depth > fragment.valuedepthLayerMap(i-1)begin
         /* Первый тест */
          bool test clip_image003[3] performDepthTest(fragment)
          if(test)  begin
            /* Второй тест */
            fragment.depth clip_image004[2] z-buffer
            fragment.color clip_image004[3] color buffer
          end
          else reject fragment
        end
        else reject fragment
      end
    end
    depthLayerMap(i) clip_image003[4] capture(z-buffer)
    colorLayerMap(i) clip_image003[5] capture(color buffer)
    /* Усиление ребер */
    edgeMap(i) clip_image003[6] edges(depthLayerMap(i),colorLayerMap(i))
    i++
  while(occlusionQuery() clip_image005 0 )  /* Конечное состояние */
 end



Два теста глубины

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

В последующих проходах (i > 0), мы создаем дополнительный тест для каждого фрагмента. Для этого теста мы используем текстуру с картой глубины слоя из предыдущих проходов рендера (i - 1). Затем мы установим координаты текстуры для фрагмента, чтобы они соответствовали координатам. Таким образом, обращение к текстуре, обеспечивает фрагмент z-значением, сохраненным в z-буфере от предыдущего прохода рендера.

Оба теста работают следующим образом:


  • Если текущее z-значение фрагмента больше, чем значение текстуры, которая является результатом обращения к карте слоя глубины, тогда фрагмент начинает проходить второй тест.
  • Если оба теста не проходят, фрагмент отклоняется.

Когда мы обрабатываем все фрагменты, содержимое z-буфера и цветного буфера образуют новую карту слоя глубины и цветную карту слоя. Мы можем эффективно разрабатывать дополнительные тесты глубины используя фрагмент программы.

15.2.2 Извлечение видимых и невидимых ребер

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

Более того, невидимые ребра становятся видимыми после последовательной очистки слоев глубины. Следовательно мы можем извлечь невидимые ребра используя модифицированную технику глубинной очистки (см. Листинг 15-1).

В результате, наша техника синильного рендеринга сохраняет видимые и невидимые ребра, как карты ребер, для их дальнейшего использования. На рисуноке 15-2 изображены z-буфер, буфер нормалей и результирующие карты ребер последовательности слоев глубины.

Важно что ребра, в картах ребер последовательности слоев глубины, появляются неоднократно, потому что локальные разрывы остаются при очистке лиц 3D геометрии. Рассмотрим следующие варианты:


  1. Два соединенных полигона имеют общее ребро. Один полигон закрывает другой. Разрывы в z-буфере, созданные общей гранью, остаются если мы очистим закрывающий полигон.
  2. Полигон, который частично закрывается другим полигоном, создает разрывы в z-буфере при переходе. Если мы очистим закрывающий полигон и незакрытый полигон, разрыв в z-буфере появится в этом же месте.

Рисунок 15-3 отображает оба случая. Как бы то ни было, но эффективность создания карты ребер практически не зависит от количества разрывов.

clip_image007

Рисунок 15-3 Два варианта очистки 3D геометрии

15.2.3 Составляющие синильного рендеринга

Мы составляем синильный рендеринг, используя видимые и невидимые ребра, хранимые в картах ребер в отсортированном по глубине порядке. Для каждой карты мы делаем следующее:


  • Мы текстурируем выравненную четверть, его карту ребер и объединенную карту глубин.
  • Далее мы применяем часть программы (1) отвечающую за рендеринг спрайта глубины и используем соответствующую карту глубин как ввод; (2) вычисляем RGB значение фрагмента, используя значение интенсивности ребер полученного от доступа к карте ребер, например синеватый цвет; и (3) установка альфа-значения интенсивности ребра.
  • Затем мы используем смешивание цветов, учитывая значения интенсивности ребер, как смешивающих факторов для обеспечения сложности глубины.

Мы обнаружили, что на практике, достаточно смешать несколько цветных карт слоя, для создания синильного рендеринга. Оставшиеся карты слоя теряют визуальный эффект, потому что цветных в них только несколько пикселей. Чтобы изменить условия окончания рендеринга и тем самым оптимизировать его скорость, мы точно определяем минимальную часть фрагментов (в зависимости от разрешения окна) при проходе теста глубины. Таким образом, мы сокращаем количество проходов рендера, при этом сохраняя качество на высоком уровне. Для оптимального соотношения скорости и качества, мы настраиваем запрет на продолжительные запросы. Рисунок 15-4a отображает результаты синильного рендеринг для кривошипного механизма.

clip_image008

Рисунок 15-4 Различные применения в технике

15.2.4 Маскировка глубины

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


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

Модификации данного метода показаны в псевдокоде Листинг 15-2.

Листинг 15-2. Псевдокод с измененными условиями окончания метода маскировки глубины
procedure depthPeeling(G clip_image003[7] 3DGeometry,
C clip_image003[8] geometryOfOccludedComponent) begin
   depthMask clip_image003[9] depthTexture(C)
   quad clip_image003[10] createTexturedScreenAlignedQuad(depthMask)
   renderDepthSprite(quad)    /* Рендеринг четверти как спрайт глуубины */
   int Q = occlusionQuery()  /* Количество фрагментов объекта */
   . . .
   do
   . . .
 renderDepthSprite(quad)
 int R = occlusionQuery()   /* Количество видимых фрагментов
 объекта */
  while(R<fraction(Q))         /* Конечное состояние */
 end

15.2.5 Визуализация строений с использованием синильного рендеринга


Синильный рендеринг может быть использован для отрисовки архитектурных зданий. Мы применяем синильный рендеринг для создания планов зданий. При составлении этих планов используется ортогональная камера с простыми задачами. При визуализации Храма Рамзеса II в Абудосе (Рисунок 15-4b), мы можем увидеть комнаты, колонны и статуи. Таким образом, синильный рендеринг увеличивает визуальное восприятие изображения. Эти планы создаются автоматически.

Обзор в перспективе улучшает ориентацию в пространстве и упрощает понимание синильного рендеринга в архитектуре. Рисунок 15-4c отображает дизайн входа и внутреннего двора храма со статуями. Подсвеченные статуи находятся перед входом в заднюю часть храма. С помощью маскировки глубины, мы определяем число слоев глубины, которые закрывают эти статуи, и очищаем их. Таким образом, мы можем уменьшить визуальную сложность проекта, если структурная сложность модели - больше, чем можно разумно отобразить.

Синильный рендеринг и поверхностное рисование–Часть 2

 

Ссылка на статью оригинал:

GPU Gems - Chapter 15. Blueprint Rendering and "Sketchy Drawings"

 

15.3 Поверхностный рендеринг

Техника поверхностного рисования рассматривает наиболее важные видимые ребра и поверхностные цвета для создания неоднородного наброска 3D геометрии.

Метод работает следующим образом: Как и синильный рендеринг, сначала мы создаем промежуточные результаты рендеринга, которые отображают ребра и поверхностные цвета 3D геометрии. Затем мы применяем неопределенные значения в пространстве изображения для создания неоднородного текстурированного наброска. И наконец мы регулируем информацию глубины таким образом, чтобы результат поверхностного рисования можно было объединить с остальными объектами 3D сцены.

15.3.1 Грани и цветные заплатки

Мы опять используем технику улучшения ребер, для сохранения ребер 3D геометрии как карты ребер, чтобы использовать ее позднее, как показано на Рисунке 15-5а. Кроме того мы рендерим поверхностные цвета 3D геометрии для текстурирования созданных цветных заплаток, кажущихся плоскими, затем накладываем все поверхностные детали и эмулируем в мультипликационном стиле. Мы называем эту текстуру картой теней; см. Рисунок 15-5b.

clip_image001

Рисунок 15-5 Применение неопределенных ребер и карт теней

15.3.2 Применение неопределенности

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

В дополнение мы введем степень неопределенности для контроля суммы возмущений, для которой мы используем произвольную матрицу 2х2. Мы умножаем значения неопределенности, получившиеся от перемножения шумов текстуры на матрицу, и затем используем полученный вектор смещения для переноса координат текстуры. Рисунок 15-6 иллюстрирует возмущения в координатах текстуры, дающие доступ к карте теней, используя степень неопределенности.

clip_image002

Рисунок 15-6 Применение неопределенности в изображении

Для увеличения эффекта наброска, мы создадим возмущение в координатах текстуры другим способом. Мы применяем две различные матрицы 2х2, результатом являются различные степени неопределенности для каждой карты. Одна степень неопределенности смещает координаты текстуры на карте ребер, другая на карте теней— другими словами, мы двигаем их в противоположные стороны. Рисунок 15-5 изображает ребра и карты теней после применения неопределенностей.

Мы обозначим значения текстуры, соответствующих фрагментам 3D геометрии, как внутренняя область; значения текстуры не соответствующих фрагментам 3D геометрии назовем внешняя область. В заключении, текстурирование четверти и возмущение координат текстуры, используя неопределенности, мы можем обратиться к внутренним краям ребер и карт теней, несмотря на то, что начальные координаты текстуры будут обращаться к внешнему краю и обратно (Рисунок 15-6). Таким образом, внутренний край может быть нарисован за границей 3D геометрии, и внешний край может проникать во внутренний. Мы можем выравнивать наброски за границами 3D геометрии(Рисунок 15-5).

И наконец, мы объединяем значения текстуры ребер и карт теней. Мы умножаем интенсивность значений, принятых от возмущения карты ребер, на значения цветов,
принятых от возмущения карты теней. Для поверхностного рисования на Рисунке 15-7a, мы устанавливаем значения неопределенности (offs , offt ) используя функцию турбулентности (основана на шуме Перлина):

      offs clip_image003 turbulence(s, t); and offt clip_image003[1] turbulence(1 - s, 1 - t);

clip_image004

Figure 15-7 Различные стили Sketchy Rendering

15.3.3 Регулирующая глубина

До сих пор, мы просто текстурировали выравненную четверть с эскизным описанием. Этот метод имеет значительные недостатки. Когда мы рендерим текстурированную четверть с текстурированной 3D геометрией, то, (1) z-значений оригинальной геометрии нет во внутренней области, и в частности, (2) никаких z-значений оригинальной геометрии нет во внешней области когда мы применяем неопределенность. Таким образом поверхностный рендеринг не может правильно взаимодействовать с другими объектами в сцене.

Чтобы преодолеть эти недостатки, мы применяем рендеринг спрайта глубины, учитывая предыдущие возмущения. Таким образом, мы дополнительно текстурируем четверть с картой глубины высокой точности (уже существует) и обращаемся к ней, дважды используя возмущение в координатах текстуры. В первом возмущении, мы применяем степень неопределенности для обращения к карте ребер; во втором возмущении мы применяем степень неопределенности для обращения к карте теней. Минимальным значением для обоих значений текстур является создание заключительных z-значений фрагмента, для тестирования глубины. Рисунок 15-5c' показывает результат обоих возмущений, примененных для карты глубин. Внутренний край возмущенной карты глубины соответствует сочетанию внутренних областей возмущений карты ребер и возмущений карты теней.

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

15.3.4 Варианты поверхностного рендеринга

Мы представляем два варианта поверхностного рендеринга, оба работают в реальном времени.

Шероховатый профиль и цветные переходы

Хотя мы делаем набросок ребер и поверхностных цветов неоднородно, профили и цветные переходы поверхностного описания остаются точными, как если бы мы делали набросок карандашом на плоской поверхности. Мы придаем профилю шероховатость и цветные переходы для симуляции различных способов рисования, например рисование мелом на шероховатой поверхности. Мы применяем случайно выбранные значения шумов; следовательно, смежные значения шумовой текстуры являются некоррелированными. Следовательно, степени неопределенности, которые мы применяем к координатам текстур смежных фрагментов, также являются некоррелированными. Таким образом, мы делаем поверхностное описание со сглаженными и потертыми ребрами, и цветными переходами, как на Рисунке 15-7b. Шероховатость и степень детализации, особенно ребер, моделируется изменением давления, как при рисовании мелом. Этот эффект зависит от количества неопределенности, которую мы применяем для изображения.

Дорисовка ребер

Фундаментальной техникой рисования рукой, для получения рисунка или схемы, является многократная дорисовка ребер. Мы сделаем набросок только визуально важных ребер для симуляции этой техники. Для этого, мы исключаем карту теней, но многократно применяем карту ребер, используя различные степени неопределенности и возможно различные цвета ребер. В этом случае ребра будут наложены неоднородно и получится впечатление, что ребра 3D геометрии неоднократно дорисовывались, как на Рисунке 15-7c. Мы также должны отредактировать информацию глубины, многократно обращаясь к карте глубины, используя соответствующие степени неопределенности.

15.3.5 Управление неопределенностью

Управление значениями неопределенности, позволяет нам настраивать визуальное появление поверхностного рендеринга. Обеспечивая значения неопределенности, основанные на функции шума Перлина для каждого пикселя изображения, (1) мы получаем последовательность кадров, как например при взаимодействии со сценой (потому что соседние значения неопределенности коррелированы), и (2) мы можем обратиться к внутренним областям из внешних и наоборот, а также сделать набросок за границами 3D геометрий. Однако, значения неопределенности остаются неизменными в изображении и не имеют явных соответствий геометрических свойств оригинальной 3D геометрии. Следовательно, поверхностное рисование стремится "плавать" в изображении (известен как эффект душевой двери) и мы не можем определить его появление.

Чтобы преодолеть эти ограничения, мы стремимся сделать следующего:


  • Сохранение геометрических свойств, как положения поверхности, нормали, или информацию кривых для вычисления значений неопределенности.
  • Продолжайте обеспечивать значения неопределенности, как можно ближе к 3D геометрии.


Сохранение геометрических свойств

Чтобы сохранить геометрические свойства 3D геометрии при управлении неопределенностью, мы делаем следующее:


  1. Мы рендерим геометрические свойства прямо в текстуру, чтобы создать дополнительный G-буфер.
  2. Далее мы текстурируем выравненную четверть дополнительной текстурой, и обращаемся к геометрическим свойствам через координаты текстуры (s, t).
  3. И, наконец, мы высчитываем значения неопределенности, основанных на функции шума, используя геометрические свойства в качестве параметров.

Затем, мы можем использовать значения неопределенности для определения различных степеней неопределенности, чтобы получить возмущение координат текстуры (s', t'). Математически, мы используем следующую функцию, чтобы определить возмущенные координаты текстуры (s', t'):







f : (s, t) clip_image003[2](s', t')


f (s, t) = p(s, t, g(s, t)),


где (s, t) являются координатами текстуры фрагмента, полученного от растеризации выравненной четверти, g() делает доступными геометрические свойства в дополнительной текстуре, и p() определяет возмущение примененное к (s, t), используя g() в качестве входа.

Для поверхностного рендеринга, мы применяем две функции f(s, t), чтобы обработать возмущения различных карт ребер (fEdge (s, t)) и теней (fShade (s, t)).

Расширение геометрии

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

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

15.3.6 Уменьшение эффекта душевой двери

Теперь покажем как управлять наброском для уменьшения эффекта душевой двери.

Мы создаем расширенную 3D геометрию с объектными координатами, как значение цветов в текстуре. Для этого мы определяем координаты объекта в пространстве для каждой из смещенных вершин и определяем их, как координаты текстуры в ходе растеризации. Тогда rasterizer создает координаты объекта в пространстве для каждого фрагмента. Специальный фрагмент программы построения теней выводит их, как значение цвета высокой точности для текстуры высокой точности. Таким образом, g(s, t) сохраняет позиции объектного пространства.

Основываясь на g(s, t), мы можем определить координаты текстуры f (s, t) используя p(). В нашем примере, функция p() высчитывает возмущение произвольной матрицы 2х2 и с помощью функции шума Перлина кодируется в 3D текстуру. Затем мы обращаемся к 3D текстуре, используя g(s, t) в качестве координат текстуры. Мы умножаем получившееся значение текстуры на матрицу 2х2, в результате получаем степень неопределенности. Затем функцию f (s, t) применяем степень неопределенности для возмущения (s, t), результатом становится (s', t').

Вычисляем fEdge (s, t) и fShade (s, t), используя различные результаты матриц в описании поверхности, в Рисунке 15-8. Рисунок 15-8 иллюстрирует весь процесс поверхностного рендеринга, учитывая основные геометрические свойства.

clip_image006

Рисунок 15-8 Буферы и результаты промежуточного рендеринга необходимые в Sketchy Rendering

Хотя этот пример просто уменьшает эффект душевой двери, он дает подсказку относительно того, как управлять поверхностными описаниями, используя геометрические свойства. Используя высокоуровневый язык затенения, такой как GLSL (Рост 2004) или Cg (Марк и др. 2003), можно далее проектировать и стилизовать наброски.


15.4 Заключение


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

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

Робастные множественные зеркальные отражения и преломления–Часть 1

 

Ссылка на оригинал статьи:

http://http.developer.nvidia.com/GPUGems3/gpugems3_ch17.html

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

После того, как мы представили основной механизм трассировки вторичных лучей, мы представляем приложения, включающие одиночные и множественные отражения и преломления на неровных поверхностях. Для вычисления множественных отражений и преломлений, собственный вектор, сохраненный в картах расстояний, прочитывается и используется для генерации отражающихся/преломляющихся лучей. Эти лучи старшего порядка трассируются так же, как и при первом отражении, фрагментарным шейдером. Интенсивность отраженного луча вычисляется в соответствии с упрощенной формулой Френеля, которая также подходит для металлов. Результирующий алгоритм прост в применении, запускается в режиме реального времени и достаточно точен для определения самоотражения. Применение нашего предложенного метода требует поддержки динамического ветвления.

 

17.1 Введение

Синтез изображений вычисляет яркость точек, которые видимы через пиксели виртуальной камеры. Локальные модели освещения вычисляют яркость из локальных свойств – таких как позиция, нормальный вектор и данные о материале – в дополнение к глобальным параметрам источника света. Каждая точка затеняется независимо, что открывает большое количество возможностей для параллельных вычислений. Эта независимая и параллельная концепция затенения широко применяется в современных GPU. Как бы то ни было, для идеальных отражателей и преломителей, яркость точки зависит также от освещения других точек; таким образом, точки не могут быть затенены независимо. Это условие означает, что вычисление яркости точки рекурсивно генерирует новую видимость и задания вычисления цвета для определения интенсивности непрямого освещения.

Основная операция для решения проблемы видимости точки на направлении – трассировка луча. Для получения полного пути нам следует продолжить трассировку луча в целевой точке, чтобы получить вторую точку и точки дальнего рассеивания. GPU производят трассировку лучей с одинаковым источником очень эффективно, делая "фотографию" из совместного источника луча и используя фрагментарный шейдер для вычисления яркости видимых точек. Процесс фотографирования привлекает растеризацию геометрии сцены и использование z-буфера для нахождения первых целей лучей, проходящих через пиксели.

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

Объекты сцены могут быть encoded как набор параметров уравнения поверхности, схожим с классической трассировкой луча (Havran 2001, Purcell et al. 2002, и Purcell et al. 2003). Если геометрия сцены слишком сложная, может быть использовано замещение простыми геометриями, что позволяет быстро аппроксимировать пересечения (Bjorke 2004 и Popescu et al. 2006).

С одной стороны, геометрия сцены может быть сохранена в упрощенной форме. Старейшее применение этой идеи – это карта глубин, используемая теневым алгоритмом, (Williams 1978), которая сохраняет свето-пространственные координаты z для части геометрии, которая видна из позиции света через окно.

Для того чтобы охватить все направления, нам следует использовать кубическую карту вместо одиночного изображения глубин. Если мы сохраняем мировое евклидово расстояние в текселях, кубическая матрица становится похожей на сферическую карту (Patow 1995 и Szirmay-Kalos et al. 2005). Таким образом, пара направлений и значения расстояния определяет точку, видимую на направлении, без знания ориентации сторон карты-куба. Это свойство очень важно, когда мы выполняем интерполяцию между двумя направлениями, так как это избавляет нас от беспокойства о границах сторон карты-куба. Эти кубические карты, сохраняющие значения расстояния, называются картами расстояния.

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

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

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

17.2 Трассировка вторичных лучей

Предложенный алгоритм трассировки луча работает на геометрии, сохраненной в расслоенных картах расстояний. Один из этих слоев – кубическая карта, где тексель содержит свойства о материале, расстояние и нормальный вектор точки, которая находится в направлении текселя. Свойство материала – это отраженная яркость для диффузных поверхностей и множитель Френеля при перпендикулярном освещении для зеркальных отражателей. Для преломителей индекс преломления также сохраняется как свойство материала. Расстояние измеряется из центра кубической карты (то есть от опорной точки).

17.2.1 Generation of Layered Distance Maps

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

Набор слоев, представляющий собой сцену, в общем случае может быть получен очисткой глубины (Everitt 2001 и Liu et al. 2006). Для управления количеством слоев, мы можем ограничить количество очищающих проходов, таким образом, мы располагаем дальние объекты в одном слое в не зависимости от того, пересекают ли они друг друга, как показано на Рисунке 17-1. Если расстояние до дальних объектов значительно больше, чем размер отражающего объекта, эта аппроксимация допустима.

clip_image001

Рисунок 17-1 Расслоенная карта расстояний с 3 + 1 слоями

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

Когда объекты сцены двигаются, карта расстояний должна быть обновлена.

17.2.2 Трассировка луча в расслоенных картах расстояний

Основная идея рассмотрена с использованием подписей Рисунка 17-2. Вектора мест точек представлены строчными буквами, и вектора направлений обозначены прописными буквами. Пусть центр нашей координатной системы o является опорной точкой, и мы заинтересованы в освещении точки x в направлении R.

clip_image002

Рисунок 17-2 Направленная трассировка

Точка освещения расположена на луче уравнения x + R · d, где d – параметр луча, необходимый для определения. Мы можем проверить точность случайной аппроксимации d, прочитав расстояние окружающей поверхности, сохраненное с направлением l = x + R · d в кубической матрице (|l'|), и сравнив его с расстоянием аппроксимированной точки l на луче |l|. Если |l| ≈ |l'|, тогда мы нашли пересечение. Если эта точка на луче на поверхности, что равно |l| < |l'|, текущая аппроксимация отклонена вниз. С другой стороны, когда точка |l| за поверхностью (|l| > |l'|), аппроксимация отклонена вверх.

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

Линейный поиск

Точки возможного пересечения находятся на луче. Таким образом, пересечение может быть найдено проходом луча (то есть проверкой точек r(d) = x + R · d, сгенерированных с возрастающей последовательностью положительного параметра d, и определением первой пары последующих точек, где одна точка отклонена вверх, в то время как остальные отклонены вниз). Это реальное пересечение, then, лежит между этими двумя предположениями и найдено с использованием секущего поиска (это будет рассмотрено в следующем подразделе).

Определение пересечений параметра луча d нуждается в более тщательном рассмотрении, потому что теперь геометрия упрощена, и проверка того же образца несколько раз при игнорировании других образцов не имеет ценности. К сожалению, выполнение равномерных шагов на луче не гарантирует, что пространство текстуры равномерно упрощено. При удалении от опорной точки, шаги единичной длины на луче соответствуют меньшим шагам в пространстве текстур. Эта задача может быть решена проходом на линейном сегменте, который выглядит идентично лучу от опорной точки, за исключением того, что его две крайние точки на одном и том же расстоянии. Конечные точки такого линейного сегмента могут быть получены проекцией начала луча, r(0) и конца луча, r() на единичную сферу, результатом которой станут новое начало s = x/|x| и конечная точка e = R/|R|, соответственно. Пересечение должно быть найдено в текселях, которые видимы в направлении между s и e, как показано на Рисунке 17-3.

clip_image003

Рисунок 17-3 Проход на луче, выполняющего равномерные шаги в пространстве текстур

Алгоритм пересечения ищет те тексели, которые делают равномерные шаги на линейном сегменте s и e:

clip_image005

clip_image007

Соответствие между параметрами луча d и t может быть найдено проекцией r' на луч, которая управляется следующей формулой:

clip_image009

Применение фрагментарного шейдера должно брать входные параметры источника луча x и направления Rтакже кубическая карта – карта типа samplerCUBE проходит как uniform-параметр – и последовательно генерирует параметры луча d и точки на луче r, и возвращает параметр отклонения вниз dl и параметр отклонения вверх dp. Отношения |l|/|l'| и |p| / |p'| представлены переменными llp и ppp соответственно. Значения расстояния сохранены в альфа-канале кубической карты. Листинг 17-1 показывает алгоритм для выполнения линейного поиска фрагментарным шейдером.

Алгоритм находит пару последующих точек отклонения вниз и вверх в одиночном слое, подготавливаясь к созданию равномерных шагов Dt на луче в пространстве текстур. Размер шага Dt установлен пропорционально длине линии сегмента s и e и разрешению кубической карты. Установив шаг текселя Dt больше, чем расстояние между двумя соседними текселями, мы ускоряем алгоритм, но увеличиваем возможность потери отражения тонких объектов. В текселе значение расстояния получается из альфа-канала кубической карты. Заметьте, что мы используем функцию texCUBElod() – установку множественного отображения уровня точно в 0 – вместо texCUBE(), потому что texCUBE(), как tex2D(), ускорит компилятор DirectX 9 HLSL для развертывания динамического цикла (Sander 2005).

Линейный поиск должен запускаться для каждого слоя. Слой, где параметр луча (dp) минимальный, содержит первую цель луча.

Ускорение со значениями расстояния Min-Max

Для ускорения поиска пересечения на слое мы вычислим минимальное и максимальное значения расстояния для каждой карты расстояний. Когда трассировка луча произведена, луч пересекается сферами с центрами в опорной точке и радиусом, равным минимальному и максимальному значениям. Две точки пересечения значительно влияют на пограничное пространство луча. Процесс передвигает начальную точку s и конечную точку e ближе, так что меньшее количество шагов перехода даст ту же точность. См. Рисунок 17-4.

clip_image010

Рисунок 17-4 Min-Max ускорение

Example 17-1. Выполнение линейного поиска фрагментарным шейдером в HLSL

1. float a = length(x) / length(R);

2. bool undershoot = false, overshoot = false;

3. float dl, llp; // Параметр луча и |l|/|l'| последнего отклонения вниз

4. float dp, ppp; // Параметр луча и |p|/|p'| последнего отклонения вверх

5. float t = 0.0001f;

6. while( t < 1 && !(overshoot && undershoot) ) {  // Итерация

7. float d = a * t / (1-t);  // Параметр луча, соответствующий t

8.   float3 r = x + R * d;  // r(d): точка на луче

9. float ra = texCUBElod(map, float4(r,0)).a; // |r'|

10. if (ra > 0) {  // Подходящий тексель, то есть ничего не видимо

11. float rrp = length(r)/ra;  //|r|/|r'|

12. if (rrp < 1) {  // Отклонение вниз

13.       dl = d;  // Сохранение последнего отклонения вниз в dl

14.       llp = rrp;

15.       undershoot = true;

16.     } else {  // Отклонение вверх

17.       dp = d;   // Сохранение последнего отклонения вверх как dp

18.       ppp = rrp;

19.       overshoot = true;

20.     }

21.   } else {  // Ничего не видимо: перезапуск поиска

22.     undershoot = false;

23.     overshoot = false;

24.   }

25.  t += Dt;  // Следующий тексель

26. }

 
   float a = length(x) / length(R);
bool undershoot = false, overshoot = false;
float dl, llp;  // Ray parameter and |l|/|l'| of last undershooting
   float dp, ppp;  // Ray parameter and |p|/|p'| of last overshooting
   float t = 0.0001f;
while( t < 1 && !(overshoot && undershoot) ) {  // Iteration
   float d = a * t / (1-t);  // Ray parameter corresponding to t
   float3 r = x + R * d;  // r(d): point on the ray
   float ra = texCUBElod(map, float4(r,0)).a; // |r'|
   if (ra > 0) {  // Valid texel, i.e. anything is visible
   float rrp = length(r)/ra; //|r|/|r'|
   if (rrp < 1) {  // Undershooting
      dl = d;  // Store last undershooting in dl
      llp = rrp;
      undershoot = true;
    } else {  // Overshooting
      dp = d;   // Store last overshooting as dp
      ppp = rrp;
      overshoot = true;
    }
  } else {  // Nothing is visible: restart search
    undershoot = false;
    overshoot = false;
 }
 t += Dt;  // Next texel
}

Очистка секущим поиском

Линейный поиск предоставляет первое простую пару последующих примеров отклонений вниз и вверх, так что реальное пересечение должно лежать между этими точками. Пусть параметры отклонения луча вниз и вверх – dp и dl , соответственно. Соответствующие две точки на луче – p и l и две точки на поверхности – p' и l', соответственно, как показано на Рисунке 17-5.

clip_image011

Рисунок 17-5 Очистка секущим шагом

Приняв то, что поверхность между точками p' and l' гладкая, мы наблюдаем ее пересечение лучом в точке r = x + R · dnew , где

clip_image013

Если одиночный секущий шаг не дает результатов достаточной точности, можно заменить одну из предыдущих аппроксимаций dl или dp (всегда сохраняя одно отклонение и одну отклоняющуюся аппроксимацию), используя dnew, и мы сможем продолжить с этого итерационного шага. Заметьте, что секущий поиск получает точные результаты для плоских поверхностей за один итерационный шаг и требует только конечного числа шагов для плоских сеток. Листинг 17-2 показывает применение фрагментарного шейдера при секущем поиске.

Пример 17-2. Применение фрагментарного шейдера при секущем поиске в HLSL

1. for(int i = 0; i < NITER; i++) {

2. // Параметр луча нового пересечения

3. dnew = dl + (dp-dl) * (1-llp)/(ppp-llp);

4.  float3 r = x + R * dnew;  // Новая точка на луче

5. float rrp = length(r)/ texCUBElod(map, float4(r,0)).a; // |r|/|r'|

6. if (rrp < 0.9999) {  // Отклонение вниз

7. llp = rrp; // Сохранить как последнее отклонение вниз

8. dl = dnew;

9. } else if (rrp > 1.0001) {  // Отклонение вверх

10. ppp = rrp; // Сохранить как последнее отклонение вверх

11. dp = dnew;

12. } else i = NITER;

13. }

   for(int i = 0; i < NITER; i++) {
  // Ray parameter of the new intersection
  dnew = dl + (dp-dl) * (1-llp)/(ppp-llp);
  float3 r = x + R * dnew;  // New point on the ray
   float rrp = length(r)/ texCUBElod(map, float4(r,0)).a; // |r|/|r'|
   if (rrp < 0.9999) {  // Undershooting
    llp = rrp;  // Store as last undershooting
    dl = dnew;
  } else if (rrp > 1.0001) {  // Overshooting
    ppp = rrp;  // Store as last overshooting
    dp = dnew;
  } else i = NITER;
}

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