В настоящее время я разрабатываю игровой движок, который использует поля расстояний со знаком в качестве метода рендеринга для отображения плавной процедурной геометрии (генерируемой с помощью простых примитивов, подобных тем, которые есть в вашей ссылке на данный момент, с целью реализации фракталов Джулии и IFS в будущем). Так как мой движок сфокусирован на процедурном генерировании и должен определять фигуры таким образом, чтобы они были удобны для лучников, я думаю, что у меня есть подходящее место, чтобы ответить на этот вопрос: P.
Что касается потоковой передачи, простое решение состоит в том, чтобы использовать какой-либо типизированный буфер и выбрасывать его в графический процессор, когда вы хотите выполнить марширование лучей. Каждый элемент буфера является сложным типом (например, структура в C / C ++), и каждый тип содержит элементы, определяющие, какую функцию вы должны использовать для его представления, его положение, поворот, масштаб и т. Д., А также средний цвет. Затем процесс упрощается до:
- Отберите свою сцену в управляемое подмножество (обратите внимание, что выборка усеченного контура и отбор окклюзии в любом случае частично выполняются алгоритмом лучевого марширования)
- Передайте подмножество в ваш буфер ввода рендера
- Передайте буфер в графический процессор, если его там еще нет, затем визуализируйте вашу сцену обычным традиционным маршированием лучей. Вам нужно будет выполнить какой-то пошаговый поиск, чтобы оценить, какой элемент во входном буфере находится ближе всего к каждому лучу для каждой итерации луча, и вам нужно будет применить преобразования к любому из лучей (в этом случае вам нужно будет инвертировать вращение фигуры, прежде чем они достигнут GPU) или сами функции расстояния (перемещение источника функции для изменения положения, регулировка, например, длины кубической стороны для изменения масштаба и т. д.). Самый простой подход - просто изменить лучи до вы передаете их фактической функции расстояния до ядра.
Что касается цвета фигур, помните, что шейдеры позволяют вам определять сложные типы, а также примитивы;). Это позволяет вам бросить все в структуру в стиле C, а затем передать эти структуры обратно из вашей функции расстояния.
В моем движке каждая структура содержит расстояние, цвет и идентификатор, который связывает его с соответствующим определением фигуры во входном буфере. Каждый идентификатор выводится из окружающего контекста соответствующей функции расстояния (поскольку моя функция отображения проходит через входной буфер, чтобы найти ближайшую цифру к каждому лучу для каждого шага, я могу смело обрабатывать значение счетчика цикла при вызове каждого SDF в качестве идентификатора фигуры для этой функции), в то время как значения расстояния определяются с использованием произвольной базовой SDF (например,point - figure.pos
для сферы), а цвета определяются либо по среднему цвету соответствующего элемента в буфере рисунка (следовательно, поэтому полезно хранить идентификатор фигуры рядом), либо по процедурному цвету, взвешенному по отношению к сохраненному среднему значению (одним примером может быть счетчик итераций для некоторой точки на Мандельбульбе, отображающий ваш «средний цвет» из цветового пространства FP в целочисленное цветовое пространство, а затем использующий сопоставленный цвет в качестве палитры, XOR (сопоставляя его с счетчиком итераций).
Процедурные текстуры - другой подход, но я никогда не использовал их сам. iq провел довольно много исследований в этой области и опубликовал несколько интересных демонстраций по Shadertoy, так что это может быть одним из способов сбора дополнительной информации.
Независимо от того, является ли ваш цвет статичным для каждой фигуры, процедурно сгенерированным или волшебным образом отобранным из процедурной текстуры, основная логика одинакова: абстрактные фигуры в некоторый вид промежуточного сложного типа (например, в структуру) сохраняют как локальное расстояние, так и локальное цвет в экземпляре этого типа, затем передайте сложный тип как возвращаемое значение из вашей функции расстояния. В зависимости от вашей реализации, выходной цвет может затем напрямую переходить на экран или следовать точке столкновения в ваш код освещения.
Я не знаю, было ли вышеупомянутое достаточно ясным или нет, так что не беспокойтесь о том, что что-то не имеет смысла. Я не могу привести примеры кода GLSL / пиксельного затенения, так как я работаю с HLSL и вычисляю затенение, но я счастлив попробовать все, что я сначала не написал правильно :).