Як реалізується підписане дистанційне поле Ray Marching для динамічного світу?


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.

Що стосується потокової передачі, найпростішим рішенням є використання введеного буфера якогось типу та перекинути його на GPU, коли ви хочете зробити маршируючий промінь. Кожен елемент буфера є складним типом (наприклад, структура в C / C ++), і кожен тип містить елементи, що визначають, яку функцію слід використовувати для її представлення, її позицію, обертання, масштаб тощо та середній колір. Потім процес спрощується до:

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

Що стосується кольорів фігури, пам’ятайте, що шейдери дозволяють визначати складні типи, а також примітиви;). Це дозволяє перекинути все на структуру у стилі С, а потім передати ці структури назад від функції дистанції.

У моєму двигуні кожна структура містить відстань, колір та ідентифікатор, які прив'язують її до відповідного визначення фігури у вхідному буфері. Кожен ідентифікатор виводиться з оточуючого контексту відповідної функції відстані (оскільки моя функція відображення проходить через вхідний буфер, щоб знайти найближчу цифру до кожного променя для кожного кроку, я можу сміливо обробляти значення лічильника циклу, коли викликається кожен SDF як ідентифікатор фігури для цієї функції), тоді як значення відстані визначаються за допомогою довільної основної SDF (наприклад,point - figure.pos для сфери), а кольори або визначаються із середнього кольору відповідного елемента в буфері фігури (отже, чому корисно зберігати ідентифікатор фігури навколо) або через процедурне забарвлення, зважене до збереженого середнього (один приклад може бути прийнятим підрахунок ітерації для деякої точки на Мандельбулі, відображення вашого "середнього кольору" з кольорового простору FP на цілий кольоровий простір, потім використання відображеного кольору як палітри, XOR'ing його проти кількості ітерацій).

Процедурні текстури - це інший підхід, але я сам ніколи їх не використовував. iq провів досить багато досліджень у цій галузі та розмістив кілька цікавих демонстрацій на Шадертої, так що це може бути одним із способів зібрати додаткову інформацію.

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.