230 likes | 368 Views
Geometria obrazu Wykład 9. Renderowanie. Usuwanie niewidocznych powierzchni. Z-bufor (bufor głębokości). Algorytm malarza. Binary Space Partition Drzewa ósemkowe. Portale. Niezgodność półpłaszczyznowa.
E N D
Geometria obrazuWykład 9 • Renderowanie. • Usuwanie niewidocznych powierzchni. • Z-bufor (bufor głębokości). • Algorytm malarza. • Binary Space Partition • Drzewa ósemkowe. • Portale. • Niezgodność półpłaszczyznowa.
Renderowanie (rendering, obrazowanie) - to w grafice trójwymiarowej komputerowa analiza modelu danej sceny i utworzenie na jej podstawie dwuwymiarowego obrazu wyjściowego w formie statycznej lub w formie animacji. Renderowanie jest wykonywane przez większość programów do grafiki 3D, np. 3D Studio Max, Cinema 4D, Lightwave 3D, Cobalt (komercyjne), Blender, POV-Ray (ogólnodostepne). [http://en.wikipedia.org/wiki/Cobalt_(CAD_program)] [http://en.wikipedia.org/wiki/POV-Ray]
Przykłady. Blender Art Gallery http://archive.blender.org/features-gallery/gallery/index.html POV-Ray Hall of Fame http://hof.povray.org/
Podstawowe etapy renderingu: • Orientacja sceny. • Lokalizacja źródeł światła. • Rzutowanie na płaszczyznę. • Eliminacja niewidocznych powierzchni. • Dostosowanie obrazu. • Rasteryzacja.
Usuwanie niewidocznych powierzchni. Aby stworzyć dwuwymiarowy obraz odpowiadający trójwymiarowej scenie, przede wszystkim musimy określić w każdym pikselu obrazu obiekt, który ma być widoczny w tym pikselu. W tym celu musimy znaleźć obiekt, który znajduje się najbliżej obserwatora wzdłuż prostej przechodzącej przez dany piksel (zakładamy, że możemy jednoznacznie przypisać obiekt pikselowi). [de Berg et al.. „Geometria obliczeniowa. Algorytmy i zastosowania.”]
y Z-bufor. przekształć scenę tak, aby kierunek patrzenia był dodatnim kierunkiem osi z; {Nadaj wszystkim komórkom bufora B (odpowiadającym pikselom obrazu) wartość +} B[x,y] := +; for każdy obiekt O sceny do if z-owa współrzędna punktu obiektu z[O] jest mniejsza od wartości przechowywanej w odpowiedniej komórce bufora B[x,y] then B[x,y] := z[O]; z x
W z-buforze przechowujemy informacje na temat położenia najbliższych punktów sceny odpowiadających poszczególnym pikselom obrazu. W pomocniczym buforze ramki trzymamy informacje o intensywności barwy danego obiektu. Złożoność algorytmu dla n obiektów wynosi O(n|S|), gdzie |S| określa docelowy rozmiar obrazu. W celu przyspieszenia obliczeń można zastosować odcinanie tylnych powierzchni (pomijamy analizę ścian, których wektor normalny skierowany jest przeciwnie do obserwatora).
Przykład. W przypadku bliskich lub przecinających się powierzchni (np. kartka papieru na stole) mogą pojawić się zaburzenia obrazu (z-fighting) spowodowane błędami zaokrągleń. [http://en.wikipedia.org/wiki/z-fighting]
y Algorytm malarza. uporządkuj elementy sceny względem ich odległości od obserwatora; for najdalszy obiekt to najbliższy do każdemu pikselowi odpowiadającemu punktowi analizowanego obiektu przypisz ten obiekt; Złożoność algorytmu dla n obiektów i obrazu rozmiaru |S| wynosi O(n log n + n|S|). z x
Niestety nie zawsze daje się uporząd-kować elementy sceny. Wtedy rozwiązaniem jest podział elementów sceny na mniejsze kawałki, które można już uporządkować.
3 2 6 5 4 1 1 2 3 6 5 4 Binary Space Partition. Załóżmy, że obiektami sceny są trójkąty a h(t) oznacza płaszczyznę zawierającą t. Algorytm 3DBSP(S); Dane: zbiór S={t1, ..., tn} trójkątów w R3. Wynik: drzewo BSP dla S. if card(S) 1 then stwórz drzewo T, w którym pamiętamy S; return T else S+{t h(t1)+: t S}; T+ 3DBSP(S+); S-{t h(t1)-: t S}; T- 3DBSP(S-); Stwórz drzewo T z korzeniem v, poddrzewami T+ i T- oraz S(v) = {t T : t h(T)}; return(T);
4 2 5 8 7 6 3 1 1 3 2 4 6 5 7 8 Możemy nieco zmodyfikować poprzedni algorytm. Algorytm 3DRANDOMBSP(S); Dane: zbiór S={t1, ..., tn} trójkątów w R3. Wynik: drzewo BSP dla S. Wygeneruj losową permutację t1, ..., tn; for i := 1 to n do użyj h(ti) do podziału każdej komórki, na którą podział ma wpływ;
Twierdzenie. Oczekiwana liczba obiektów tworzonych przez algorytm 3DRANDOMBSP wynosi O(n2). Dowód. Oszacujmy oczekiwaną liczbę fragmentów, na które jest rozcinany dany trójkąt tk S. Niech dla trójkąta ti, gdzie i < k, li = h(ti) h(tk). Dla prostych li, które przecinają tk definiujemy si = litk. Jeśli lk-1 dzieli tk, to ma nowe podziały powstają tylko w ścianach dotych-czasowego podziału, które sąsiadują z krawędziami tk. Podobnie jest dla pozostałych prostych. Z twierdzenia strefowego wynika, że liczba krawędzi w strefie wyznaczanej przez k prostych wynosi O(k). Zatem krawędzie trójkąta tk należą do ścian podziału mających w sumie O(k) krawędzi. Zatem średnia liczba podziałów ścian przecinanych przez si jest stała, czyli trójkąt tk jest dzielony na średnio O(k) elementów. Stąd oczekiwana całkowita liczba fragmentów podziału jest kwadratowa.
Drzewo ósemkowe. Konstrukcja drzewa ósemkowego polega na otoczeniu całości sceny trójwymiarowej sześcianem (lub prostopadłościanem), który następnie dzielony jest na osiem przystających części. Proces ten jest rekurencyjnie powielany aż do otrzymania jednorodnych elementów. Najczęściej boki sześcianu są równoległe do osi układu współrzędnych co ułatwia obliczenia.
Zastosowanie drzew ósemkowych. • Efektywna reprezentacja voxeli (przechowujemy grupy jednorodnych voxeli). • Odrzucanie niewidocznych obiektów (dla scen ograniczonych). • Algorytm. • Zacznij analizę od korzenia drzewa. • Jeśli sześcian odpowiadający danemu węzłowi drzewa jest niewidoczny z pozycji obserwatora, to niewidoczne jest całe poddrzewo. • Jeśli przynajmniej część sześcianu odpowiadającego danemu węzłowi drzewa jest widoczna, to analizuj węzły poddrzewa odpowiadające widocznym sześcianom. • Inny sposób analizy niż w przypadku drzew BSP, gdyż nie korzysta się tu z algorytmu malarskiego.
3. Wykrywanie kolizji obiektów (badamy minimalne sześciany zawierające dane obiekty). • 4. Kwantyzacja kolorów (algorytm Gervautz & Purgathofer 1988). • Kodujemy kolory na i-tym poziomie drzewa przez 4r+2g+b, gdzie r, g, b są i-tymi znaczącymi bitami odpowiednich barw. Tworzymy ścieżki do liści odpowiadających kolorom występującym w obrazie. Dostajemy drzewo o głębokości co najwyżej 8. Chcąc zmniejszyć liczbę kolorów postępujemy w następujący sposób: • usuwamy pojedyncze liście o największej głębokości, • łączymy sąsiadujące liście odpowiadające małej liczbie pikseli (minimalizujemy błąd), • usuwamy liście odpowiadające największej liczbie pikseli (zaburzamy nieco kolor, ale zyskujemy na rozmiarze drzewa). • Kończymy, gdy liczba kolorów będzie zgodna z oczekiwaniami.
Portale. Rozważmy podział przestrzeni na wielo-ścienne obszary (sektory). Ściany wielościanów mogą być przepusz-czalne lub nie. Przepuszczalne ściany nazywamy portalami. Umożliwiają one przejście między obszarami (stanowią relację widzialności między obszarami). W celu renderowania sceny tworzymy graf sąsiedztwa dla obszarów podziału i badamy obiekty widoczne przez portale (badając kolejne obszary lub ich widzialne wycinki). Jest to dość kosztowne rozwiązanie.
Portale mają tę własność, że jeśli portal jest niewidoczny, to niewidoczny jest również obszar za nim. Z drugiej strony, umożliwiają analizę odbić lustrzanych. Podczas renderowania można skorzystać z list PVS (zbiorów potencjalnie widocznych – można je używać również z drzewami BSP i OCT ). Wierzchołkami grafu PVS są sektory a krawędziami – portale. Idealnym byłby podział na małe (mało obiektów do identyfikacji), wypukłe (łatwość obróbki) sektory. Gdy obserwator widzi kolejne sektory poprzez portale, powstaje piramida widzenia.
procedure portal-render(S) for każdy portal P należący do S do if P jest widoczny then begin S’ := sektor sąsiadujący z S przez P; portal-render(S’); end; Algorytm S := sektor, w którym znajduje się obserwator; portal-render(S);
Problemy renderowania. Obraz Powiększenie obrazu Zbiór punktów próbnych
S(h) = 0,3 S(h) = 0,05 (h) = 0,25 Niezgodność półpłaszczyznowa. Niech U = [0,1][0,1] oraz niech S będzie zbiorem punktów próbnych w U. Niech H oznacza zbiór wszystkich domkniętych półpłaszczyzn prze-cinających U oraz h H. (h) = pole powierzchni h U S(h) = card(h U S) / card(S) S(h) = |(h) - S(h)| H(S) = suphHS(h)
Określanie niezgodności półpłaszczyznowej. • Wystarczy badać półpłaszczyzny, których brzeg zawiera punkty ze zbioru S. • Wartości S(h) są określane przez poziomy odpowiednich krawędzi układu prostych dualnych do zbioru S. • Dla każdej z krawędzi łatwo można obliczyć wartość (h), a co za tym idzie S(h) i H(S). • Wniosek. • Dla danego zbioru n punktów próbnych S niezgodność półpłaszczyznową H(S) można obliczyć w czasie O(n2).