RENDERING W CZASIE RZECZYWISTYM Michał Radziszewski
Plan wykładu Mapowanie nierówności wprowadzenie Poziomy szczegółowości Cieniowanie w układzie stycznym Generacja wektorów normalnych i stycznych Mapy wysokości i mapy normalnych Zastosowania, konwersje pomiędzy formatami Mapowanie normalnych Ograniczenia technik, symetria, krawędzie, oświetlenie
Plan wykładu c.d. Mapowanie przesunięcia tekstury Mapowanie przemieszczeń i teselacja Automatyczna generacja tekstur normalnych i tekstur wysokości Technika hi-poly to lo-poly Kompresja tekstur a mapy normalnych MIP-mapping i mapowanie nierowności
Literatura J. F. Blinn, Simulation of Wrinkled Surfaces, SIGGRAPH 1978 T. Welsh, Parallax Mapping with Offset Limiting: A Per-Pixel Approximation of Uneven Surfaces, Infiscape Corp. 2004 Z. Brawley, N. Tatarchuk, Parallax Occlusion Mapping: Self-Shadowing, Perspective-Correct Bump Mapping Using Reverse Height Map Tracking, in Shader X3, Charles River Media 2004
Literatura c.d. Matyas Premecz, Iterative Parallax Mapping with Slope Information, Central European Seminar on Computer Graphics 2006 E. Lengyel, Computing Tangent Space Basis Vectors for an Arbitrary Mesh, Terathon Software 3D Graphics Library 2001
Mapowanie nierówności wprowadzenie Stosowane w celu uzyskania wrażenia bardziej szczegółowej geometrii Karty graficzne uzyskują najlepszą wydajność gdy trójkąty na ekranie nie są mniejsze niż ok. 16 pikseli Rozmiar ten jest o wiele za duży aby oddać niewielkie detale obiektu Obiekty są cieniowane w taki sposób, aby wyglądały na o wiele bardziej złożone niż są w rzeczywistości
Mapowanie nierówności wprowadzenie
Mapowanie nierówności wprowadzenie
Mapowanie nierówności wprowadzenie W podstawowej technice nierówności są podkreślane tylko za pomocą światła Nie są zatem widoczne w cieniu Nie są też widoczne na sylwetkach obiektu Założenie: nierówności modelowane przy pomocy techniki cieniowania muszą być małe w porównaniu z rozmiarem trójkątów obiektu Założenie to jest łatwe do spełnienia, gdyż ta technika jest przeznaczona do modelowania detali
Poziomy szczegółowości Dobór poziomu szczegółowości powinien zależeć od wielkości obiektu na ekranie Wielkość wyrażona w pikselach Nawet duże obiekty powinny być uproszczone, jeżeli są odpowiednio daleko od obserwatora Nieodpowiedni dobór poziomu szczegółowości Aliasing, znikające i pojawiające się prymitywy Albo wyraźnie widoczne trójkąty, słaba jakość grafiki
Poziomy szczegółowości c.d. W uproszczeniu wybór jednej z trzech technik w zależności od rozmiaru prymitywów na ekranie Trójkąty, jeżeli są większe niż ok. 16 pikseli Mapowanie nierówności dla szczegółów większych niż 1 piksel, a zbyt małych dla efektywnego renderingu trójkątów Cieniowanie dla szczegółów mniejszych niż pojedynczy piksel W grafice off-line: często stosowana technika micro-polygon
Cieniowanie w układzie stycznym Przestrzenie, w których zazwyczaj jest przeprowadzane cieniowanie Przestrzeń świata Przestrzeń widoku Przestrzeń styczna W każdej przestrzeni otrzymany wynik jest taki sam, równania mogą być mniej lub bardziej złożone Wektory V i L można łatwo przetransformować do jednej z pierwszych dwóch przestrzeni
Cieniowanie w układzie stycznym Aby sprowadzić wektor do przestrzeni stycznej, należy go pomnożyć przez odwrotność macierzy złożonej z wektorów [T, B, N] Wektory te muszą mieć długość równą 1 Wektor N powinien być ortogonalny do T i B
Generacja normalnych Obiekty 3D często nie posiadają zdefiniowanych normalnych Można je wygenerować na podstawie siatki Niech P[i] oznacza tablicę pozycji, a N[i] normalnych Tablica pozycji zawiera poprawne wartości, a normalnych ma same zera Każdy trójkąt jest zdefiniowany jako 3 indeksy i 0, i 1, i 2 Obliczenie normalnej dla każdego trójkąta i dodanie jej do pozycji w tablicy N: N[i 0 ], N[i 1 ] i N[i 2 ] Normalizacja wszystkich wektorów z tablicy N
Generacja normalnych c.d. Obliczenie normalnej dla trójkąta: A = P[i 2 ] P[i 0 ] B = P[i 1 ] P[i 0 ] Normal = A B Normalną można normalizować, wtedy w każdym wierzchołku będzie policzona średnia normalna ze wszystkich trójkątów posiadających ten wierzchołek Brak normalizacji średnia ważona, wagą jest pole powierzchni trójkąta
Generacja stycznych Obiekty 3D często nie posiadają też zdefiniowanych stycznych Jeżeli tylko obiekt posiada współrzędne tekstury (tzw. uv), to na ich podstawie można wygenerować styczne Mając styczne (T i B) można o wiele łatwiej wygenerować normalne, N = T B Uwaga na zwrot normalnej!
Generacja stycznych c.d. Niech P 0, P 1, P 2 oznaczają pozycje wierzchołków Niech (u 0, v 0 ), (u 1, v 1 ), (u 2, v 2 ) oznaczają współrzędne tekstury w wierzchołkach Oznaczenia: Q 1 = P 1 P 0, (s 1, t 1 ) = (u 1 u 0, v 1 v 0 ), Q 2 = P 2 P 0, (s 2, t 2 ) = (u 2 u 0, v 2 v 0 ), Wtedy: T B s t 1 2 1 s 2 t 1 t2 s 2 t s 1 1 Q Q 1 2
Mapy wysokości Tekstura w skali szarości Opisuje wysokość (przesunięcie wzdłuż normalnych) punktów odpowiadających poszczególnym tekselom Może być ze znakiem lub bez W tym pierwszym przypadku możliwe jest przesuniecie punktów zarówno na zewnątrz obiektu jak i w kierunku jego środka
Mapy wysokości c.d.
Mapy normalnych Tekstury RGB w których zapisane są normalne dla punktów odpowiadających tekselom Kodowanie na ogół 8-bit bez znaku Odczyt z tekstury: normal = tex( )*2.0 1.0 Dekodowanie normalnej do wartości ze znakiem Niedokładne brak możliwości zakodowania zera 0-1.0, 127-1.0/255.0, 128 1.0/255.0, 255 1.0 Lepiej: normal = tex( )*255.0/127.0 1.0 Wtedy 0.0 jest kodowane przez 127, a wartość 255 jest nieużywana
Mapy normalnych c.d.
Konwersja normalne wysokość Konwersja może być wykonana w obie strony Konwersja z mapy wysokości do normalnych jest prosta Konwersja w drugą stronę jest o wiele trudniejsza Obie konwersje są stratne ze względu na precyzję Mapa normalnych może przechowywać dane nie odpowiadające żadnemu polu wysokości Zwykle jest to uznawane za błąd w modelu Mapa normalnych przechowuje nadmiarowe informacje, które mogą być niespójne
Konwersja wysokość normalne Niech h[i,j] oznacza wysokość w punkcie (i,j) Może być ze znakiem albo bez Wtedy normalną można obliczyć w ten sposób: N x = h[i + 1, j] h[i 1, j] N y = h[i, j + 1] h[i, j 1] N z = C C jest dowolną stałą większą od 0, wynikającą ze skali pola wysokości Normalną należy jeszcze znormalizować
Konwersja normalne wysokość Mapa normalnych jest gradientem mapy wysokości Całkowanie mapy normalnych Stała całkowania: wysokość jednego z tekseli (np. lewy górny róg) można przyjąć dowolnie Obliczanie kolejnych tekseli: h[i + 1, j] = h[i, j] + N x /N z h[i, j + 1] = h[i, j] + N y /N z Obliczanie wysokości kolejnych punktów
Konwersja normalne wysokość Startując od wybranego punktu, pozostałe punkty można obliczyć na wiele sposobów Wyniki mogą być za każdym razem nieco inne ze względu na precyzję obliczeń Jeżeli mapa normalnych jest niepoprawna, to wyniki mogą być całkiem różne Algorytmy iteracyjne
Mapowanie normalnych Najprostsza technika mapowania nierówności Wymaga mapy normalnych Przechowuje ona normalne w układzie stycznym Jeżeli cieniowanie jest obliczane w układzie stycznym, to wystarczy zastąpić normalną geometryczną przez normalną odczytaną z tekstury Technika oparta o cieniowanie, nierówności nie widać na obiektach nieoświetlonych bezpośrednio i na sylwetkach obiektów
Mapowanie przesunięcia tekstury
Mapowanie przesunięcia tekstury Zjawisko paralaksy efekt niezgodności różnych obrazów tego samego obiektu obserwowanych z różnych kierunków Symulacja tego zjawiska dla płaszczyzn, które udają że mają złożoną geometrię Obliczenie nowych współrzędnych tekstury na podstawie położenia obserwatora, mapy wysokości i oryginalnych współrzędnych tekstury
Mapowanie przesunięcia tekstury Odczyt koloru i normalnych na podstawie nowo obliczonych współrzędnych Algorytmy o różnym stopniu komplikacji i możliwościach różnią się między sobą sposobem obliczania współrzędnych tekstury z paralaksą Często najprostszy algorytm daje zadowalające wyniki (ale nie zawsze!)
Mapowanie przesunięcia tekstury Przecięcie promienia widoku z powierzchnią teksturowaną zmodyfikowaną mapą wysokości Najprostszy algorytm założenie: pole wysokości jest płaskie w otoczeniu przecinanego punktu Obliczenia w przestrzeni stycznej: offset = h*v xy /V z Nowe współrzędne tekstury: oryginalne + offset Ograniczenie przesunięcia: offset = h*v xy
Mapowanie przesunięcia tekstury Bardziej zaawansowany algorytm śledzenie promieni w przestrzeni tekstury Podstawowy wariant: w pętli odczyt z tekstury i sprawdzenie czy promień nie przecina się z powierzchnią Bardziej zaawansowane metody wymagają tekstur przechowujących więcej informacji, ale znacznie szybsze W pewnych sytuacjach umożliwia osiągnięcie lepszych rezultatów niż algorytm najprostszy
Mapowanie przesunięcia tekstury
Mapowanie przemieszczeń Generowanie geometrii na podstawie map wysokości Wymagana jest karta z obsługą teselacji Do renderingu przekazywany jest bardzo uproszczony model Następnie tworzony jest na GPU obły model, nie zawierający detalu, ale tez bez ostrych krawędzi Wierzchołki takiego modelu są następnie przemieszczane na podstawie mapy przemieszczeń
Mapowanie przemieszczeń
Automatyczna generacja tekstur Tekstury normalnych i wysokości mogą być malowane przez grafików albo generowane automatycznie Często spotykanym podejściem jest wykonanie dwóch wersji geometrii tego samego modelu, tzw. hi-poly (szczegółowa) i lo-poly (uproszczona) Tekstury generowane są wtedy tak, aby zapewnić złudzenie wyglądu geometrii w wersji szczegółowej, podczas gdy faktycznie renderowana jest wersja uproszczona
Automatyczna generacja tekstur Algorytm generacji oparty o śledzenie promieni Obiekty uproszczony i szczegółowy umieszczane są w tym samym punkcie w świecie Dla każdego teksela odnajdywany jest odpowiadający mu punkt na obiekcie uproszczonym Z punktu tego, wzdłuż normalnej geometrycznej, śledzony jest promień przecina się on z obiektem szczegółowym
Automatyczna generacja tekstur Znajdowany jest najbliższy punkt przecięcia, w kierunku zgodnym z normalną albo przeciwnym do niej Zachowanie ciągłości odpowiedni wybór kierunku (zgodny albo przeciwny do normalnej) Odległość między punktami można zapisać do mapy wysokości Podobnie normalną obliczoną dla modelu szczegółowego
Automatyczna generacja tekstur
Automatyczna generacja tekstur
Automatyczna generacja tekstur
Automatyczna generacja tekstur
Kompresja tekstur normalnych Kompresja tekstur do formatu, który karta graficzna potrafi dekodować sprzętowo W OpenGL 2.x tylko trzy formaty, algorytm S3TC, odpowiedniki DXT1, DXT3 i DXT5 z DirectX DXT2 i DXT4 nie są obecnie używane Tzw. premultiplied alpha, format sprawia problemy Od wersji 3.x o wiele więcej możliwosci
Kompresja tekstur normalnych Formaty DXT1, DXT3 i DXT5 RGB (DXT1) albo RGBA (DXT3 i DXT5) Bloki 4x4 teksele Zapamiętane dwa kolory Pozostałe są interpolowane liniowo Niezależna kompresja kanału alfa (DXT 3 i DXT5) Liniowa zależność kolorów nie sprawdza sie dobrze dla normalnych Zależności pomiędzy N x, N y i N z są nieliniowe
Kompresja tekstur normalnych Nowy format od wersji OpenGL 3.0: niezależna kompresja dwóch kanałów Normalne przechowywanie wartości N x i N y Normalna jest znormalizowana i N z >= 0 Zatem N z = (1 N x 2 N z2 ) 0.5 Takie podejście daje o wiele lepsze wyniki
Kompresja tekstur normalnych
Kompresja tekstur normalnych
Kompresja tekstur normalnych
MIP-mapping i mapowanie nierówności Filtrowanie tekstur normalnych powoduje zanik szczegółów Nie daje to dobrego efektu dla obiektów połyskliwych Dla obiektów tego typu można ograniczać połysk wraz z utratą detali na kolejnych poziomach szczegółowości
Dziękuję za uwagę