W jaki sposób realizowany jest Marching Ray Field Signed Distance dla dynamicznego świata?


10

Wydaje mi się, że rozumiem podstawy Marching Ray Field Signed Distance. Modelujesz scenę za pomocą szeregu pól odległości (takich jak: http://iquilezles.org/www/articles/distfunctions/distfunctions.htm ), a następnie dla każdego piksela rzucanego promieniem zacznij od początku promienia , znajdź odległość do najbliższego obiektu w tym punkcie i zwiększaj punkt o najbliższą odległość, aż coś trafisz. Udało mi się zrobić prosty renderer i właśnie tam kończy się większość opisów techniki.

Pozostawia mi to kilka pytań, w jaki sposób można wykorzystać SDF Ray Marching w scenariuszu z prawdziwego świata:

Pytanie 1: W prawdziwej grze scena jest zwykle złożona i ładowana na procesor, z wieloma dynamicznymi obiektami. Rozumiem podstawowe culling okluzji (takie jak oktany), a przy renderowaniu wielokątnym tworzyłbym listę (na CPU) elementów w widoku frustrowanym do renderowania.

Wyobraź sobie, że mam bardzo złożoną scenę z wieloma postaciami i dynamicznymi obiektami poruszającymi się po ekranie, kontrolowanymi przez CPU. Jak przesyłać strumieniowo obiekty, które chcę renderować do GPU w każdej ramce? Każdy przykład ma scenę zakodowaną na stałe w GLSL. Czy ktoś może udostępnić przykład poziomu dynamicznie przesyłanego strumieniowo do modułu cieniującego?

Pytanie 2: W jaki sposób obiekty mogą mieć wiele kolorów? Funkcje odległości zwracają tylko odległość, ale w jaki sposób implementacje często zwracają kolor? (np. uderzyłeś w czerwoną kulę, a nie w niebieski sześcian.) Gdyby to była implementacja procesora, mogłabym wywołać funkcję globalną wewnątrz funkcji odległości, gdy jest to trafienie kończące marsz promienny, i które mogłoby również przekazać obiekt trafionego tekstura / kolor. Ale jak zwrócisz kolor lub teksturę przedmiotu w GLSL?

Dziękuję Ci.

Odpowiedzi:


2

To minimalna odpowiedź, ale chciałem udostępnić informacje na wypadek, gdybyś nie uzyskał lepszej odpowiedzi.

Jeśli chodzi o to, jak prawdziwe gry wykorzystują marsz ray, zwykle nie. Dopiero w ciągu ostatnich kilku lat gry zaczęły porządkować bufor głębi, aby wykonać odbicia przestrzeni ekranu, ale żadna gra, o której wiem, że nie używa marszowania promieni w sposób opisany przez ciebie - jeszcze?

W przypadku innego pytania o kolory i tym podobne, ludzie zwykle kojarzą materiały z przedmiotami i używają „współrzędnych tekstury” punktu, w którym promień uderza w obiekt, aby ustalić właściwości materiału w tym punkcie na obiekcie. Do typowych materiałów należą takie kolory, jak kolor rozproszony, intensywność zwierciadła, kolor emisyjny oraz wskaźnik przezroczystości / załamania światła.

Mam nadzieję, że jest to dla ciebie przynajmniej pomoc! Możesz również uzyskać dobre odpowiedzi ze strony wymiany stosów graficznych.


2
„brak gry, o której wiem, że używa marszowania promieniowego w sposób, w jaki opisujesz” nadchodząca gra Media Molecule Dreams używa podpisanych pól odległości do rzeźbienia treści generowanych przez użytkowników, ale jeśli dobrze rozumiem, pola są konwertowane na chmurę punktów do renderowania zamiast być zgranym bezpośrednio. Ten artykuł może mieć kilka pomysłów: dualshockers.com/2015/08/15/…
DMGregory

1
@DMGregory Fajnie, ale myślę, że nie jest to ściśle Ray Marching. Więc punkt jest nadal aktualny, gry zwykle nie używają marszu ray.
concept3d

1
Aktualizacja tego wątku - nadchodząca gra Claybook podobno renderuje swoje sceny przy użyciu promieni wystrzeliwanych bezpośrednio przez pola odległości , zamiast najpierw przekształcać je w konwencjonalną geometrię. Więc „jeszcze?” wydaje się, że zostało to potwierdzone dwa lata później. :)
DMGregory

1

Obecnie rozwijam silnik gry, który wykorzystuje podpisane pola odległości jako technikę renderowania, aby wyświetlać płynną geometrię proceduralną (generowaną za pomocą prostych prymitywów, takich jak na razie w twoim łączu, z zamiarem zaimplementowania fraktali Julii i IFS w przyszłości). Ponieważ mój silnik koncentruje się na generowaniu procedur i musi definiować liczby w sposób, który czyni je przyjaznymi dla ray-marchera, wydaje mi się, że jestem w dobrym miejscu, aby odpowiedzieć na to pytanie: P.

Jeśli chodzi o przesyłanie strumieniowe, najprostszym rozwiązaniem jest użycie jakiegoś buforowanego typu i wrzucenie go na GPU, gdy chcesz przeprowadzić marsz promienny. Każdy element bufora jest typem złożonym (np. Struct w C / C ++), a każdy typ zawiera elementy określające, jaką funkcję należy użyć do jego reprezentowania, jego pozycję, obrót, skalę itp. Oraz średni kolor. Następnie proces upraszcza się do:

  1. Podziel scenę na zarządzalny podzbiór (zwróć uwagę, że algorytm marszowania promieni i tak jest częściowo wykonywany automatycznie przez algorytm marszowania promienia)
  2. Przekaż podzbiór do bufora wejściowego renderowania
  3. Przekaż bufor do GPU, jeśli jeszcze go nie ma, a następnie renderuj scenę za pomocą zwykłego tradycyjnego marszu promiennego. Będziesz musiał przeprowadzić pewnego rodzaju wyszukiwanie krok po kroku, aby ocenić, który element w buforze wejściowym jest najbliżej każdego promienia dla każdej iteracji marszera promienia, i musisz zastosować transformacje do każdego promienia (w takim przypadku musisz odwrócić obroty figury, zanim dotrą one do GPU) lub same funkcje odległości (przesuwając początek funkcji dla zmian pozycji, dostosowując np. długości boków sześciennych dla zmian skali itp.) Najprostszym podejściem jest po prostu zmodyfikowanie promieni przed przekazujesz je do rzeczywistej funkcji odległości rdzenia.

Jeśli chodzi o kolory figur, pamiętaj, że shadery pozwalają definiować zarówno złożone typy, jak i prymitywy;). To pozwala ci wrzucić wszystko do struktury w stylu C, a następnie przekazać te struktury z powrotem z funkcji odległości.

W moim silniku każda struktura zawiera odległość, kolor i identyfikator, który wiąże ją z odpowiednią definicją figury w buforze wejściowym. Każdy identyfikator jest wywnioskowany z otaczającego kontekstu odpowiedniej funkcji odległości (ponieważ moja funkcja mapowania zapętla się przez bufor wejściowy, aby znaleźć najbliższą liczbę dla każdego promienia dla każdego kroku, mogę bezpiecznie traktować wartość licznika pętli, gdy wywoływany jest każdy SDF jako identyfikator figury dla tej funkcji), podczas gdy wartości odległości są definiowane przy użyciu arbitralnego rdzenia SDF (nppoint - figure.pos dla kuli), a kolory są albo definiowane na podstawie średniego koloru odpowiedniego elementu w buforze postaci (dlatego dlaczego warto zachować identyfikatory postaci) lub poprzez kolor proceduralny ważony w kierunku przechowywanej średniej (jednym przykładem może być wzięcie liczba iteracji dla pewnego punktu na żarówce Mandelbulb, mapowanie „przeciętnego koloru” z przestrzeni kolorów FP na przestrzeń kolorów całkowitych, a następnie użycie odwzorowanego koloru jako palety przez XOR'owanie go względem liczby iteracji).

Tekstury proceduralne to inne podejście, ale sam nigdy ich nie użyłem. iq przeprowadził sporo badań w tej dziedzinie i opublikował kilka ciekawych demonstracji na temat Shadertoy, dzięki czemu może to być jeden ze sposobów na zdobycie dodatkowych informacji.

Niezależnie od tego, czy kolor jest statyczny dla każdej figury, generowany proceduralnie, czy magicznie próbkowany z tekstury proceduralnej, podstawowa logika jest taka sama: abstrakcyjne figury do pewnego rodzaju pośredniego typu złożonego (np. Struktury), przechowują zarówno lokalną odległość, jak i lokalną kolor w instancji tego typu, a następnie przekaż typ złożony jako wartość zwracaną z funkcji odległości. W zależności od implementacji kolor wyjściowy może następnie przejść bezpośrednio do ekranu lub podążać za punktem kolizji do kodu oświetlenia.

Nie wiem, czy powyższe było wystarczająco jasne, czy nie, więc nie martw się pytaniem, czy coś nie ma sensu. Naprawdę nie mogę podać żadnych próbek kodu GLSL / cieniowania pikseli, ponieważ pracuję z HLSL i cieniowaniem obliczeniowym, ale z przyjemnością próbuję przejrzeć wszystko, czego nie napisałem poprawnie :).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.