Проблема аффинного преобразования 3D в трассировке лучей - PullRequest
4 голосов
/ 29 апреля 2011

All,

Я пишу довольно нетрадиционный трассировщик лучей для расчета свойств теплопередачи различных объектов в сцене.В этом трассировщике лучей случайные лучи снимаются с поверхности моих примитивных объектов в сцену для проверки пересечений.

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

Все хорошо, пока я не сделаю анизотропную шкалу, например, масштабирую объект по [2 2 1] (изотропная шкала в порядке).Это наводит меня на мысль, что я неправильно преобразовываю направленную составляющую луча.В настоящее время я преобразую направление луча из примитивного пространства в мировое пространство путем умножения направленного компонента на транспонирование матрицы обратного преобразования исходных объектов, а затем преобразую луч из мирового пространства в каждое примитивное пространство путем умножения на транспонирование преобразования целевых объектов.matrix.

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

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

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


Основной алгоритм для этого трассировщика лучей следующий:

For each object, i, in scene
{
    for each ray, r, in number of rays per object
    {
        determine random ray from primitive i
        convert ray from primitive space of i to world space

        for each object, j, in scene
        {
            convert ray to primitive space of object j
            check for intersection with object j
        }
    }
}

Надеюсь, чтобы прояснить вопрос, давайте рассмотрим пример,Предположим, у меня есть цилиндр, вытянутый вдоль оси z (единичный радиус и высота), и кольцо, лежащее в плоскости xy с внутренним диаметром 7 и внешним диаметром 8. Я хочу масштабировать цилиндр в 6 раз по x и yнаправления (но не направление z), поэтому моя аффинная матрица преобразования выглядит следующим образом:

M(cylinder) = |2 0 0 0|        M^-1(cylinder) = | .5 0. 0. 0. |
              |0 2 0 0|                         | 0. .5 0. 0. |
              |0 0 1 0|                         | 0. 0. 1. 0. |
              |0 0 0 1|                         | 0. 0. 0. 1. |

M(annulus) =  |1 0 0 0|        M^-1(annulus) =  |1 0 0 0|
              |0 1 0 0|                         |0 1 0 0|
              |0 0 1 0|                         |0 0 1 0|
              |0 0 0 1|                         |0 0 0 1|

Теперь предположим, что у меня есть луч, который имеет случайную начальную точку на поверхности цилиндра s и случайное направление отсюдаот поверхности цилиндра c, дающей луч r (os) = s + ct.

Я хочу преобразовать этот луч из примитивного (объектного) пространства в мировое пространство, а затем проверить на пересечение с другими объектами всцена (кольцо).

Первый вопрос: как правильно преобразовать луч r (os) в мировое пространство r (ws), используя M (цилиндр) или M ^ -1 (цилиндр).

Второй вопрос: как правильно преобразовать луч r (ws) из мирового пространства в пространство объекта, чтобы проверить его на предмет пересечения с другим объектом?действует с помощью M (кольцевое пространство) и M ^ -1 (кольцевое пространство).


Некоторая дополнительная справочная информация:

Это приложение для расчета радиационного теплообмена между N объектами.Луч запускается из случайной точки на объекте, причем его направление выбирается случайным образом в пределах полусферического распределения, ориентированного по нормали поверхности в случайной точке.


Вот некоторая визуализация моей проблемы.Направленное распределение лучей при его первом генерировании: Initial ray directional distribution

Если применить преобразование к мировым координатам с использованием матрицы преобразования M: Direction transformed by M

Если применить преобразование кмировые координаты с использованием матрицы обратного преобразования M ^ -1 Direction transformed by M^-1

Ответы [ 2 ]

3 голосов
/ 29 апреля 2011

Матрица обратного транспонирования поддерживает постоянную составляющей вращения, но инвертирует масштабирование.Это означает, что масштабирование все еще там.Это верно для нормалей: рассмотрим в 2d отрезок от (0,0) до (. 707, .707) .Нормальное значение составляет (-. 707, .707) .Если мы масштабируем на (с, 1) , мы получаем сегмент от (0,0) до (с * .707, .707) .В пределе, когда s становится большим, мы, по существу, имеем плоскую линию, параллельную оси x.Это означает, что нормаль должна указывать вдоль оси y.Таким образом, мы получаем нормальное значение (-. 707 / с, .707) .Однако из этого примера должно быть ясно, что преобразованный вектор больше не имеет единичной длины.Возможно, вам нужно нормализовать направленный компонент?

Если мы начнем с использования свойства, что матрица преобразования может быть представлена ​​в виде масштабирования, расположенного между двумя вращениями (в стиле SVD), мы получим, что ваша матрица исходящих преобразований выглядит следующим образомтак: R2out * Sout ^ -1 * R1out и тогда ваша матрица входящего преобразования выглядит так: R1in ^ -1 * Sin * R2in ^ -1 (как бы я хотел, чтобы SO использовал Mathjax...).Это кажется правильным, если вы заново нормализуете свои векторы.


Редактировать:

Думая об этом в одночасье, я решил, что обратное преобразование может только быть действительным для нормального случая.Рассмотрим пример выше.Если s = 2 , то наклон отрезка, изначально 1 , превращается в 1/2 .Аналогично, наклон нормали превращается из -1 в -2 .Между отрезком линии и лучом все еще остается угол 90 градусов.Все идет нормально.Теперь ... что, если рассматриваемый вектор фактически параллелен отрезку.Мы получаем наклон 2 , больше не параллельный.

Итак, я думаю, у меня есть два вопроса на данный момент.Что на самом деле идет не так в вашей программе / Что заставляет вас думать, что это неправильно?И каково правильное поведение?Возможно, вы можете сделать 2D-сюжет.

1 голос
/ 29 апреля 2011

Это только что появилось на днях в Этот вопрос

Один из ответов содержит ссылку на статью Ray Tracing News, в которой обсуждается использование транспонирования обратного преобразования для нормалей.

Я должен согласиться с JCooper в вопросе "что на самом деле идет не так?" Моя первая мысль заключается в том, что вы, похоже, моделируете теплообмен с излучением, и вы должны быть осторожны с неравномерным масштабированием объектов. Если у вас есть равномерное распределение «фотонов» на излучаемой поверхности объектов, а затем вы применяете неравномерное масштабирование этого объекта, то у вас будет неравномерное распределение фотонов, покидающих поверхность. Это одна из возможных ловушек, но поскольку вы не указываете, что происходит, трудно сказать, если это ваша проблема.

Чтобы ответить на ваши вопросы о правильном способе преобразования, перейдите по ссылке Эта ссылка на Ray Tracing News

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...