Как используется когерентность лучей для повышения скорости трассировки лучей при сохранении реалистичности?

#optimization #raytracing #raycasting

#оптимизация #трассировка лучей #raycasting

Вопрос:

Я рассматриваю возможность использования когерентности лучей в моем программном обеспечении per-pixel raycaster в реальном времени raycaster.

AFAICT, используя однородную сетку, если я назначу когерентность лучей участкам, скажем, размером 4×4 пикселя (где в настоящее время у меня по одному излучению на пиксель), учитывая 16 параллельных лучей с разными начальной (и конечной) точками, как это работает для согласованной сцены? Что я предвижу, так это:

  1. Существует расстояние, в пределах которого марш лучей будет точно таким же для смежных / похожих лучей. На таком расстоянии я экономлю на обработке. (Как я узнаю, каково это расстояние?)
  2. В итоге я получу слегка или серьезно некорректное изображение из-за того, что некоторые лучи расходились не в нужное время.

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

Наверное, я просто не понимаю, как это должно использоваться.

Ответ №1:

Если все сделано правильно, когерентность лучей не должна повлиять на конечное изображение. Поскольку лучи расположены очень близко друг к другу, есть хорошее изменение в том, что все они будут проходить по одинаковым траекториям при прохождении структуры ускорения (kd-tree, aabb-tree и т.д.). Вам приходится спускаться по каждой ветви, на которую может попасть любой из лучей, но, надеюсь, это не сильно увеличивает количество ветвей и экономит доступ к памяти.

Другим преимуществом является то, что вы можете использовать SIMD (например, SSE) для ускорения некоторых ваших тестов, как в структуре ускорения, так и против треугольников.

Комментарии:

1. Является ли ветвление заданным при трассировке пакетов лучей, чтобы облегчить перенаправление лучей на большие расстояния? Картинка нарисовала бы здесь тысячу слов. Хотел бы я найти такую.

2. Не могу найти картинку, но докторская диссертация Инго Вальда ( sci.utah.edu /~wald/Публикации/2004/// WaldPhD/download//… ) описывает это в 7.2.3 SIMD-обход пакетов для kd-деревьев.

3. Да, статья Уолда немного помогла. Я получаю то, что вы разливаете когерентные лучи в пакеты, используя SIMD, либо через SSE, либо через графический процессор. Чего я не понимаю, так это того, что происходит при попадании одного из лучей. Что-то разветвляется? Или остальные параллельные лучи просто продолжают перемещаться, пока они тоже не остановятся, и в этот момент вся операция SIMD завершается? И более того — если это так, почему бы просто не выполнить SIMD для расходящихся лучей — чтобы данные о лучах были «MD».

4. Способ, которым я делал это в прошлом, — отслеживать, какие лучи «активны» по битовому полю; если луч не пересекает ветку в дереве, очистите его бит. Вы можете прекратить обход текущей ветви, когда ни один из лучей не активен. Когда вы достигнете листа, вы можете испускать все лучи или только активные, в зависимости от того, что вы считаете более быстрым (поскольку неактивные лучи не должны попадать). Чем более когерентны ваши лучи, тем больше вероятность, что все они пройдут через одни и те же узлы в дереве и попадут в одни и те же треугольники, что позволит избежать дополнительной выборки данных.