Как реализуется марширующее поле Signed Distance Field Ray для динамического мира?


10

Я думаю, что я понимаю основы полевого луча с маршевым движением. Вы моделируете свою сцену с помощью набора полей расстояния (таких как: http://iquilezles.org/www/articles/distfunctions/distfunctions.htm ), а затем для каждого пикселя, который вы отбрасываете луч, начинайте с начала луча. найдите расстояние до ближайшего объекта в этой точке и увеличивайте точку на ближайшее расстояние, пока вы не нажмете что-нибудь. Мне удалось сделать простой рендер, и на этом большинство описаний техники заканчиваются.

Это оставляет меня с некоторыми вопросами о том, как SDF Ray Marching может быть использован в реальном сценарии:

Вопрос 1: В реальной игре сцена, как правило, сложная и загружается в ЦП со многими динамическими объектами. Я понимаю базовую выборку окклюзии (например, октодерево), и при многоугольном рендеринге я бы создал список (на процессоре) элементов в представлении просмотра для визуализации.

Итак, представьте, что у меня очень сложная сцена с множеством персонажей и динамических объектов, движущихся по экрану, управляемая процессором. Как бы я передавал объекты, которые хочу рендерить, в GPU каждый кадр? В каждом примере сцена жестко запрограммирована в GLSL. Может кто-нибудь поделиться примером динамического потока уровня в шейдер?

Вопрос 2: Как объекты могут иметь несколько цветов? Функции расстояния только возвращают расстояние, но как реализации обычно передают цвет обратно? (Например, вы попали в красную сферу, а не в синий куб.) Если бы это была реализация ЦП, я мог бы вызвать глобальную функцию внутри функции расстояния, когда это удар, чтобы завершить маркер луча, и который также мог бы передать объект попадания текстура / цвет. Но как бы вы вернули цвет или текстуру элемента в GLSL?

Спасибо.

Ответы:


2

Это минимальный ответ, но я хотел поделиться информацией, если вы не получили лучший ответ.

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

Что касается другого вопроса о цветах и ​​тому подобном, люди обычно связывают материалы с объектами и используют «текстурные координаты» точки, где луч попадает на объект, чтобы выяснить свойства материала в этой точке на объекте. Обычные материалы включают такие вещи, как диффузный цвет, интенсивность зеркального отражения, излучающий цвет и показатель прозрачности / преломления.

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


2
«Ни одна игра, о которой я знаю, использует лучевое марширование в том виде, как вы описали». Предстоящая игра Media Molecule Dreams использует подписанные поля расстояний для создания содержимого, созданного пользователем, но если я правильно понимаю, поля преобразуются в облако точек для рендеринга вместо быть непосредственно намеченным. Эта статья может иметь некоторые идеи: dualshockers.com/2015/08/15/…
DMGregory

1
@DMGregory Хорошо, но я думаю, что это не совсем Рэй Маршинг. Таким образом, точка все еще действительна, игры обычно не используют лучевой маршинг.
concept3d

1
Обновление этой ветки. По имеющейся информации, грядущая игра Claybook визуализирует свои сцены, используя лучи, попадающие непосредственно через поля расстояний , вместо того, чтобы сначала преобразовывать их в обычную геометрию. Так что "еще?" кажется, подтвердился два года спустя. :)
DMGregory

1

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

Что касается потоковой передачи, простое решение состоит в том, чтобы использовать какой-либо типизированный буфер и выбрасывать его в графический процессор, когда вы хотите выполнить марширование лучей. Каждый элемент буфера является сложным типом (например, структура в C / C ++), и каждый тип содержит элементы, определяющие, какую функцию вы должны использовать для его представления, его положение, поворот, масштаб и т. Д., А также средний цвет. Затем процесс упрощается до:

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

Что касается цвета фигур, помните, что шейдеры позволяют вам определять сложные типы, а также примитивы;). Это позволяет вам бросить все в структуру в стиле C, а затем передать эти структуры обратно из вашей функции расстояния.

В моем движке каждая структура содержит расстояние, цвет и идентификатор, который связывает его с соответствующим определением фигуры во входном буфере. Каждый идентификатор выводится из окружающего контекста соответствующей функции расстояния (поскольку моя функция отображения проходит через входной буфер, чтобы найти ближайшую цифру к каждому лучу для каждого шага, я могу смело обрабатывать значение счетчика цикла при вызове каждого SDF в качестве идентификатора фигуры для этой функции), в то время как значения расстояния определяются с использованием произвольной базовой SDF (например,point - figure.pos для сферы), а цвета определяются либо по среднему цвету соответствующего элемента в буфере рисунка (следовательно, поэтому полезно хранить идентификатор фигуры рядом), либо по процедурному цвету, взвешенному по отношению к сохраненному среднему значению (одним примером может быть счетчик итераций для некоторой точки на Мандельбульбе, отображающий ваш «средний цвет» из цветового пространства FP в целочисленное цветовое пространство, а затем использующий сопоставленный цвет в качестве палитры, XOR (сопоставляя его с счетчиком итераций).

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

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

Я не знаю, было ли вышеупомянутое достаточно ясным или нет, так что не беспокойтесь о том, что что-то не имеет смысла. Я не могу привести примеры кода GLSL / пиксельного затенения, так как я работаю с HLSL и вычисляю затенение, но я счастлив попробовать все, что я сначала не написал правильно :).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.