Parametryzacja materiałów w silniku Unreal Engine 5. Materiały jako część zmiennego środowiska sceny.

Materiałowanie, obok procesu modelowania, jest najważniejszym procesem twórczym każdego grafika 3D. Statyczny model 3D (tzw. Static Mesh w silnikach Unreal) składa się z geometrii (mesh) oraz pokrycia jego powierzchni — materiału. Sam materiał w grafice komputerowej jest niewyczerpanym źródłem zagadnień, których nie da się uszeregować, nie określając jego fundamentalnych cech i pojęć. W tym artykule nie będzie dużo mowy o teksturach, które gdyby się tak zastanowić, są właściwie formą pośrednią pomiędzy geometrią 3D a rastrami (obrazami 2D). Tutaj będzie mowa głównie o materiałach pozbawionych zmienności definiowanej przez tekstury — o materiałach parametrycznych. Z drugiej strony, materiał parametryczny o odpowiednim stopniu komplikacji, może uzyskać taką zmienność na obszarze powierzchni modelu, iż będzie nierozróżnialny od teksturowanego [Rys. 1.]. U podstawy jednak zawsze informacja, której nośnikiem jest tekstura, zawarta zostanie w pikselach, a w przypadku materiału parametrycznego, wyliczana jest z matematycznych formuł jego shaderów.

[Rys. 1. Obraz symulujący głębokie pole gwiazd, wygenerowany wyłącznie parametrycznie, operując głównie wzorami szumu typu Voronoi i shaderami post-procesowego przetwarzania obrazu. Rysunek autora.]

Materiały parametryczne

Zostawiając teraz tekstury z tyłu, można przejść do materiałów, które są definiowane za pomocą wyłącznie parametrów. Parametry, w przeciwieństwie do tekstur są informacją globalną dla całego materiału. Nawet wtedy, kiedy ich przetwarzanie buduje zmienność na powierzchni modelu. Materiał o parametrze koloru np. czerwonym, będzie czerwony na przestrzeni całej powierzchni modelu, którą będzie pokrywać [Rys. 2.].

[Rys. 2. Przykład prostego materiału PBR, wyłącznie parametrycznego. Jest zdefiniowany jedynie poprzez barwę i połysk. Zmienność na jego powierzchni, to efekt reakcji odbić otoczenia na pojedynczy i tylko skalarny parametr połysku. Rysunek autora.]

Jeśli jednak barwa będzie sterowana bardziej złożonym wzorem matematycznym, którego parametr będzie zmienną, może to doprowadzić do powstawania zmiennych obrazów na powierzchni całego obiektu [Rys 3.]. Co ciekawe, stopień komplikacji obrazów, który może osiągnąć dosłownie nieskończoność (jak obrazu fraktalnego prezentowany na rys. 2.), wciąż pozostaje generowany za pomocą garści liczb i operacji matematycznych. 

[Rys. 3. Materiał parametryczny przedstawiający wyliczoną iteracyjnie zbieżność sprzężenia zwrotnego typu Mandelbrot. Wynik dodatkowo zwizualizowany przez parametr PBR połysku, odbijający otaczający obraz HDR. Rysunek autora.]

Już tutaj widać ogromną przewagę takich materiałów — ich tzw. ściśliwość informacyjna jest nieporównywalnie większa niż ściśliwość informacyjna tekstur, których pojemność zmniejszać można jedynie do pewnego stopnia, przy pomocy kompresji i praktycznie zawsze ze stratą informacji.

Obecnie w grafice 3D używa się głównie materiałów PBR. Są to w skrócie materiały, które odtwarzają fizyczne cechy powierzchni rzeczywistych elementów. Metale, które obserwujemy w rzeczywistym otoczeniu, posiadają nie tylko swoje barwy, ale również… metaliczność. Przez to potrafią odbijać barwę przedmiotów, od których pada na nie światło, a nie tylko jego natężenie. Plastik może być połyskliwy lub matowy — w obu przypadkach może posiadać ten sam kolor, lecz wyglądem będą się różnić diametralnie. Innymi parametrami są przeźroczystość (Opacity), załamanie światła (Refraction) czy bardziej wyrafinowane, jak na przykład informacja o rozpraszaniu światła wewnątrz obiektu 3D (Subsurface Scattering).

Wymiary parametrów

Parametry jako cechy globalne mogą być wyrażane za pomocą wartości o zmiennej ilości wymiarów. Stopień połysku wyraża się w silniku UE za pomocą skalarnego parametru z zakresu 0 (pełny połysk, lustro) do 1 (pełny mat). Metaliczność wyraża się również za pomocą skalara i również z zakresu wartości 0 do 1. W przypadku metali parametr 0 oznacza materiał niemetaliczny, a 1 pełen metal. Zarówno dla parametrów połysku, jak i metalu, oba skalary mają postać liczby typu floating-point (specyficzna podgrupa liczb rzeczywistych). Odrobinę bardziej zaawansowanym przykładem parametru materiału jest jego barwa. Barwy nie da się wyrazić za pomocą wartości skalarnej (z wyjątkiem czystych odcieni szarości). W silniku UE stosuje się do tego wektor o trzech wymiarach, z których każdy odpowiada trzem kanałom barwy RGB. Wektor taki, operujący również w zakresie barw 0 (czerń) do 1 (biel) dla każdego kanału, może przedstawić każdą, praktyczną barwę. Jako iż będzie to wciąż pojedynczy parametr (pomimo trzech wymiarów swojej wartości), barwa takiego materiału pokrywać będzie cały nałożony przez nią obiekt. Za pomocą tylko trzech wymienionych parametrów możemy określić na przykład materiał lustra — Połysk [0], Metaliczność [1], Barwa [1,1,1] (biel) – [Rys. 4.].

[Rys. 4. Prosta parametryczna definicja lustra w UE5. Dwie wartości skalarne – połysk i metaliczność, oraz biała barwa za pomocą wektora jednostkowego [1,1,1].]

Innym parametrem, tym razem nieco złożonym — skalar obok wektora, i nieograniczającym się do zakresu 0-1, jest tzw. Emissive — świecenie. To cecha materiału odpowiadająca za emitowanie przez obiekt “zimnego” światła. Zimnego, ponieważ w odróżnieniu od innych źródeł światła w zasadzie Emissive nie rzuca cieni, i nie oświetla otoczenia (Nie dotyczy to pewnych specyficznych metod wymuszania oświetlenia otoczenia w silnikach UE4 oraz uwzględniania Emissive przy GI Lumena w UE5). Emissive jest cechą materiału, którą dobrze jest definiować za pomocą wektora RGB (barwa świecenia) oraz wyrażać natężenie jego świecenia przez skalarny mnożnik od zera do nieskończoności [Rys. 5].

[Rys. 5. Definicja parametrycznego materiału emisyjnego. Do Emissive podłączony jest wektor z czystą barwą czerwoną [1,0,0], przemnożony przez skalar o wartości 100. Są to więc na dobrą sprawę dwa parametry zawarte w pojedynczej operacji arytmetycznej, dające na wyjściu czerwone światło o natężeniu determinowanym przez skalar.]

Hierarchia materiałów Master — Instancja

W silnikach Unreal istnieje bardzo praktyczna struktura materiałów, pozwalająca stałe parametry zamieniać na łatwe w operowaniu zmienne. Nadrzędnym pojęciem jest tutaj tzw. “Master” materiału. Master to właściwie edytor shaderów. Ma on swoje UI, charakterystyczne i podobne do wszystkich edytorów shaderów w programach graficznych. Po utworzeniu Mastera otwiera się edytor, w którym do centralnej wstęgi materiału podpina się pożądane składniki PBR [np. rys. 4.]. Odbywa się to za pomocą powszechnie przyjętej już metody rozciągania pomiędzy nodami shaderów “nici”. Parametry zdefiniowane w Masterze są domyślnie parametrami stałymi. To znaczy, że jeśli określi się w nim na przykład barwę niebieską materiału, to żeby ją zmienić, należy ten materiał przeedytować ponownie przez edytor shaderów w Masterze. Jest to o tyle niepraktyczne, że zmiana wartości materiałów nie prowadzi do zmiany wartości w runtime na scenie, bez dodatkowej kompilacji takiego materiału. O wiele wygodniej jest utworzyć tzw. “Instancję” materiałową (MI), należącą do konkretnego Mastera. Master będzie wtedy jej rodzicem (Parent). Instancja nie posiada UI pozwalającą na edycję shaderów, ale wyciąga ze swego rodzica wszystkie parametry promowane tam do zmiennych. Jeśli więc jeden z parametrów Mastera zostanie promowany do zmiennej, ta, jako wartość (skalarna lub wektor) pojawi się w instancji. Co ważniejsze, pozwala na wygodną, w trybie runtime, zmianę barwy, połysku, metaliczności, natężenia świecenia itd.

Mastery materiałów mogą być stworzone z bardzo uniwersalnymi strukturami shaderów. Mogą mieć mnóstwo parametrów promowanych do zmiennych. Nie tylko operujących na cechach PBR materiału, ale sterujących wykonywanymi na nich operacjami, logiką, czy wreszcie dynamiką ich zmiany w czasie. Posiadając bardzo uniwersalny, rozbudowany Master, można za pomocą jego instancji omateriałować całe sceny. Jest to optymalna metoda, choć z drugiej strony, jeśli master jest zbyt rozbudowany, jego nieużywane w instancjach bloki mogą negatywnie wpłynąć na wydajność sceny. Dobrym nawykiem jest utrzymywać struktury Master – Instancje przynajmniej w obrębie głównego typu shadera – Master typu opaque nie powinien (choć w zasadzie może) mieć instancję typu tranluscentnego lub apha-maskowanego.

Hierarchia Master – Instancje nie musi być w relacjach parentsiblings. Instancje mogą mieć swoje instancje – te przyjmują wartości zmiennych parametrów od swoich rodziców i same są również gotowe na ich zmiany. Podsumowując, Master służy do budowy i edycji materiału, kiedy jego Instancje, to wygodny sposób na sterowanie parametrami, które wypromowane zostały w Masterze do roli zmiennych.

Statyka materiałów

W zdecydowanej większości zastosowań materiały pełnią rolę pokrycia obiektów geometrycznych. Podobnie jak w rzeczywistości, takie pokrycie stanowi statyczny, niezmienny element grafiki, nawet jeśli obiekt, który go porusza, sam przemieszcza się na scenie. Materiały statyczne najprościej jest zdefiniować jako niezmienne w czasie. Nie ma tutaj znaczenia, że ich parametry zostały promowane do zmiennych. Zmienność poprzez promocję parametru ustawia się do konkretnego runtime`u bez możliwość jego zmiany “w trakcie gry”. Na ogół sceny nie-statyczne zyskują swoją dynamikę poprzez przemieszczanie przedmiotów, animacje, efekty cząsteczkowe czy nawet, od biedy, poprzez samą grę kamery. Dynamikę można uzyskać również za pomocą gry światła i cieni na materiale, który sam pozostaje statyczny. Przemieszczające się światło może nadać zmienności obrazowi statycznego obiektu, ze statycznym, ale reagującym na to światło materiałem (połyskliwym, przeźroczystym z parametrem refrakcji itp.). W materiale mogą odbijać się zmienne obrazy dynamicznego otoczenia. Ciągle jednak takie materiały pozostają martwe, w sensie posiadania wyłącznie statycznych komponentów. Nie znaczy to, że same materiały również nie mogą stać się aktywnym elementem sceny. 

Ożywianie sceny za pomocą dynamiki materiałów

Potężną przewagą grafiki komputerowej typu real-time jest nie tylko sama swoboda spowodowana uwolnieniem się od z góry ustalonego kadru, ale immersja związana z poczuciem zmienności w czasie elementów sceny. Oczywiście wpływają na to przede wszystkiem wyżej wymienione procesy jak animowana geometria, zmienne dynamiczne oświetlenie, zmienny postproces itd. Wszystko to jednak jest pochodną parametru czasu, który na jakimś mniej lub głębszym poziomie mają te elementy wbudowany. Również materiały mogą osiągnąć dynamikę poprzez uwikłanie zmiennych z parametrem czasu. Łatwo sobie przecież wyobrazić materiały, które zmieniają barwę, połysk, przeźroczystość i w ogóle wszystkie swoje pozostałe cechy w czasie. Przykładem móże być materiał błyskający światłem typu Emissive. Nałożony na odpowiednią geometrię może stać się na scenie odpowiednikiem sygnalizacji świetlnej. Wracając na chwilę do tekstur, można spowodować, że sam obraz tekstury również stanie się na materiale zmienny w czasie. Może się przesuwać, rotować lub w praktycznie dowolny sposób deformować.

Bardzo dobrym przykładem wykorzystania dynamiki materiałów jest światowej sławy gra, stworzona przez polskich artystów pt. “Layers of Fear” oraz jej sequel. Oba dzieła, oprócz wzorowej kompozycji scen, grafiki, prowadzenia aktorów, samego scenariusza, posiadają w mistrzowski sposób skomponowane shadery materiałów, które w wielu przypadkach potrafią w dynamiczny sposób, na oczach widza zmienić całą scenę, poprzez sterowanie teksturami i parametrami materiałów zmienną czasową [Rys. 6.]. W tej grze często dynamika materiałów odgrywa większą rolę w ożywianiu sceny niż jakiekolwiek poruszające się obiekty.

[Rys. 6. Jedna ze scen “Layers of Fear”, gdzie materiały nałożone na elementy korytarza, na oczach gracza starzeją się. W innych chwilach te same materiały można zobaczyć jako nowe, jako płonące, jako zabrudzone itp.Te same pomieszczenia przechodzą w czasie przez bardzo różne stylistyki. Źródło Internet.]

Węzeł “Time”

W silniku UE, zagadnienie dynamiki materiałów można sprowadzić do dwóch aspektów edycji materiałów. Pierwszy to wprowadzenie węzła (node) Time, który jest łącznikiem statycznego edytora materiałów z zegarem samego silnika. Dostarcza zmiennej w czasie wartości, którą można podpiąć pod praktycznie wszystkie parametry. Nie jest tutaj istotne, czy nod podaje czas w sekundach, cyklach, czasie bezwzględnym, czy konkretnym formacie. Chodzi tylko o stworzenie możliwości istnienia zmiennego w czasie parametru wewnątrz edytora materiału, do którego w trybie runtime nie było wcześniej dostępu. Od tej pory świecący materiał może zmieniać natężenie swojego światła w czasie. Przepuszczony przez funkcję Sinus sygnał będzie się zmieniał w sposób jeszcze bardziej naturalny [Rys. 7.]. Przedmioty z nałożonym materiałem transluscentnym mogą z czasem stawać się bardziej lub mniej przeźroczyste. Jeśli parametr czasu zmienia się zbyt szybko (albo zbyt wolno), można przepuścić go przez nody zwykłych operacji matematycznych — mnożenia czy dzielenia zmieniając tempo podpiętych procesów.

[Rys. 7. Prosty materiał, gdzie do parametrów sterujących natężeniem świecenia wstawiona została zmienna czasowa za pomocą węzła Time. Jego dziedzina przepuszczona przez funkcję Sinus spowodowała, że zmiany natężenia przebiegają w sposób pulsacyjny.]

Węzeł “Panner”

Drugim ważnym elementem budującym dynamikę w materiałach UE jest węzeł Panner. Jest to nod, który jako input przyjmuje między innymi Time (bez czasu nie będzie dynamiki), ale ma również tę dodatkową cechę, że modyfikuje koordynaty UV tekstur. Jest to nod w zasadzie służący do zmiany w czasie obrazów tekstur. Tutaj czas reguluje tempo przesuwania koordynat UV, przez co powstaje wrażenie przesuwania samej tekstury. Panner ma możliwość regulacji czasem dla obu koordynat niezależnie już w swoich własnych ustawieniach.

Dodatkowe modyfikacje w otoczeniu Panner’a mogą tekstury deformować lub rotować poprzez dalsze, niejednoczesne działania na każdą ze współrzędnych U i V przestrzeni UV. Najlepszym przykładem dynamicznych materiałów, gdzie w grę wchodzi przesuwanie tekstur oraz praca czasu na sinusoidalnych zakresach wartości, to materiały falującej wody. Podpięte do wody tekstury Normal Map prezentujące najczęściej obraz seamless’owego szumu typu perlin, do tego nałożone na siebie z różnymi częstotliwościami, potrafią wywołać bardzo przekonujący obraz fal na wodzie [Rys. 8.].

[Rys. 8. Fragment złożonego materiału symulującego falującą powierzchnię wody. Panner odgrywa tutaj funkcję przesuwania jednej z tekstur typu noise. Za Pannerem, w części parametryzującej koordynaty UV tekstury, widać zasadniczy nod – Time, kontrolujący tempo przesuwania tekstury.]

Taki materiał, który dodatkowo tesseluje geometrie i wywołuje offsety jej werteksów, tworzy prawdziwie geometryczny obraz 3D falującej, dynamicznej w czasie wody [Rys. 9.]. Powierzchnie falującej wody to chyba najbardziej reprezentatywne przykłady wykorzystania dynamiki sterowanej wyłącznie z głębi shaderów materiałów.

[Rys. 9. Materiał tesselujący geometrię i wymuszający offsety werteksów, tworząc reprezentację powierzchni wody morskiej. Powierzchnia ta dzięki Pannerowi posuwającemu tekstury fallo-podobne tworzy przy ich odpowiednich superpozycjach złudzenie prawdziwych fal morskich. Wszystkim kontroluje tykający parametr czasu za pomoca umieszczanego w materiale nodu Time. Źródło z Internetu.]

Dynamika materiałów kierowana przez interakcje na scenie

Ostatnim elementem układanki pozostaje sytuacja, kiedy dynamiką materiału nie będzie kierować umieszczony i pozostawiony w jego shaderach zegar, ale zmiany sterowane będą przez zdarzenia (events) na scenie. To mechanizm, w którym określona sytuacja na scenie wyzwala ewolucję zmiennej, zdefiniowanej wcześniej poprzez promocję stałego parametru. Na scenie włączony zostaje jakiś przycisk. Przełącznik poprzez Blueprinty (BP) odwołuje się do aktora (choćby geometrii reprezentującej ścianę), na którego nałożony jest materiał zawierający zmienną sterującą barwą. Event włączenia przycisku jest w stanie poprzez BP sięgnąć do takiej zmiennej i nadać jej inną wartość.

Gracz na scenie może wchodzić w interakcje z przedmiotami. Obecnie do tego stopnia, że interakcje te są w zgodzie z prawami fizyki (spadanie i odbijanie, bezwładność itd.) i dają poczucie rzeczywistego zachowania przedmiotów (aktorów sceny). Ciekawiej się robi, kiedy interakcje wzbogaci się dodatkowo o zmienne elementy materiałów. Zmiany w cechach materiałów wywoływane mogą być na przykład przez decyzje samych graczy.

Dobrym startem do takich eksperymentów może być template Unreala, wstawiający na scenie gracza w trybie first person. Gracz ten może podnieść broń, która wystrzeliwuje niewielkimi kulkami [Rys. 10.].

[Rys. 10. Scena z jednego z template UE5 z trybem gracza typu First Person. Tutaj już po edycji BP pocisku, implementującej zmiany barwy materiału po trafieniu.]

Kuliki te są zawarte w BP, w którym potrafią rozpoznać aktorów ze zdefiniowaną fizyką. Wtedy nie tylko odbijają się od nich (do tego wystarczy sam kolider, bez fizyki), ale wywołują w takich obiektach również odrzut. BP tego “pocisku” posiada już wprowadzony eventowy nod “On Hit” [Rys. 11.]. 

[Rys. 11. Przeedytowana struktura BP pocisku. Dodany stack z ustanowieniem (Set) zmiany barwy materiału na wywołanym trafieniem (On Hit) aktorze.]

Do wydarzenia On Hit, jak łatwo się domyślić, można dobudować różne zdarzenia i sytuacje, które mogą się uruchomić przy zdarzeniu uderzenia pocisku w aktora. Łatwo jest też wyobrazić sobie teraz sytuację, w której pocisk po zderzeniu z aktorem zmienia barwę trafionego obiektu [również rys. 11.]. Jeśli potrafi to zrobić, to nic nie stoi na przeszkodzie by materiał zmieniał też połysk, zaczynał świecić, uzyskiwał przeźroczystość, zaczął falować itd. Nie musi to być reakcja On Hit pocisku broni, Można tak zaprojektować dotyk, umieszczenie przedmiotu w obrębie jakiejś przestrzeni, interakcje między aktorami i ich wzajemnych stosunków przestrzennych. Wszystko to może spowodować, że materiał stanie się żywym elementem nie tylko w swojej ograniczonej do stałego upływu czasu zegara strukturze, ale również w zależności od zewnętrznych decyzji użytkownika.