Пересечение луча и треугольника


Введем следующие обозначения: P - origin луча, v - его направление. v0,v1,v2 - вершины треугольника. z - точка пересечения. t - расстояние от точки вылета луча до точки пересечения луча и треугольника. u,v,t1 - барицентрические координаты. Барицентрические координаты представляют собой отношения площадей маленьких треугольников к большому треугольнику. (рис. 1.)

x u := u/S, v := v/S, t1 := t1/S

x t1 = 1 – u - v

Рис. 1. пересечение луча и треугольника

Барицентрический тест (fast minimal storage ray triangle intersection)

Это самый известный тест на пересечение «луч-треугольник». Имея 3 точки на плоскости, можно выразить любую другую точку через ее барицентричечкие координаты. Первое уравнение берется просто из определения барицентрических координат, выражая точку пересечения z. С другой стороны, эта же точка z лежит на прямой. Второе уравнение таким образом, это просто параметрическое уравнение прямой. Прировняв правые части уравнений 1 и 2 получаем третье уравнение, которое, по сути, является системой 3-х уравнений (p,v,v1,v2,v3 - векторы) с 3-мя неизвестными (u,v,t).

 Уравение, из которых можно вывест барицентрический тест

 Проведя алгебраические преобразования получим ответ в следующем виде:

 

Юнит тест (Woop's unit test)

Основная идея данного алгоритма заключается в том, чтобы посчитать матрицу преобразования треугольника в некий единичный треугольник (отсюда название) с вершинами (1,0,0); (0,1,0); (0,0,0).  Во время подсчета пересечения луч преобразуется этой матрицей в пространство, где треугольник имеет единичное представление. После преобразования вычислить пересечение намного проще, так как нужно считать пересечение с заранее известным треугольником (1,0,0); (0,1,0); (0,0,0). Пусть задан треугольник с вершинами A,B,C.

Рис. 3. Афинное преобразование треугольника в пространство, где он имеет единичное представление.

Рассмотрим преобразование T-1:

Если применить данное преобразование к треугольнику (1,0,0); (0,1,0); (0,0,0); то получим исходный треугольник.

Для того чтобы найти нужное нам преобразование необходимо дополнить матрицу T∆-1 до 4x4 (добавить еще одну строчку (0,0,0,1)) и найти обратную матрицу. Это будет соответствовать обратному T∆-1 преобразованию. После, необходимо лишь умножить луч на полученную матрицу и посчитать пересечение с единичным треугольником.

float3 o = mul3x4(m, ray_origin);

float3 d = mul3x3(m, ray_direction);

float t = -o.z/d.z;

float u = o.x + t*d.x;

float v = o.y + t*d.y;

Функция mul3x4 выполняет умножение подматрицы 3x3 на трехмерный вектор и добавляет к результату последний столбец (3 его компоненты). Функция mul3x3 просто умножает подматрицу 3x3 на трехмерный вектор.

Немного об эффективности

Несмотря на то, что юнит-тест делает немного меньше вычислений (в худшем случае), с алгоритмической точки зрения он менее эффективен. Причина заключается в том, что в юнит-тесте сначала вычисляется координата t, а потом уже u и v. Как правило, если в сцене много мелких треугольников, именно по координатам u и v можно быстро отбросить те треугольники, которые заведомо не пересекаются.

Основное достоинства юнит-теста заключается в том, что он более экономно расходует регистры графического процессора при реализации алгоритма на GPU и его проще реализовать в железе (например на FPGA). 




<< Вернуться назад

Статьи и обзоры

Поиск пересечений

Обратная трассировка лучей

Быстрая трассировка лучей

Индустриальная основа

Фотореалистичная визуализация

GPU ray tracing

Сферические гармоники

Дружественные проекты:

OpenSource RTRT

Siberian renderer

Наши разработки

Hydra renderer

AdaRT

Публикации

Загрузить

Скриншоты и видео

ССЫЛКИ

© Copyright 2007 Владимир Фролов, Александр Фролов

При поддержке Лаборатории компьтерной графики и мультимедия ф-та ВМК МГУ
Создание сайта: Александр Фролов