Grafika komputerowa Wykład 11 Analiza widoczności
Analiza widoczności Odrzucanie wewnętrznych stron (ang. backface culling) 1) Obiekty muszą być zamkniętymi bryłami zamodelowanymi za pomocą reprezentacji brzegowej 2) Obiekty muszą być bryłami wypukłymi 3) Wektory normalne są skierowane na zewnątrz brył 4) Obserwator musi być na zewnątrz brył Posortuj powierzchnie wg odległości od obserwatora (najbardziej odległe powierzchnie na poczatku); Dla wszystkich powierzchni w malejącym porzadku: { if N*O >0 // kąt pomiędzy N i O < 90° wypełnij obszar rzutu ściany na ekranie; } Closed convex solid O – direction to observer N N N J. Sas: Advanced Computer Graphics - Simple rendering techniques – part2
Analiza widoczności Backface culling - wady Sortowanie trójkątów może być niewystarczające do określenie właściwej kolejności wyświetlania – do którego punktu trójkąta mierzyć odległość (środek, najblizszy, najdalszy???) T1 T2 Który z T1, t2 wyświetlić jako pierwszy: Sortowanie wg środków -> T2 -> źle !!! Sortowanie wg najbliższych wierzchołków -> T2 -> źle !!! Sortowanie wg najbliższych wierzchołków -> T1 -> OK … ale ta zasada nie sprawdza się dla sceny jak poniżej: T2 T1
Analiza widoczności (b) (a) Backface culling – inne metody wyboru ściany do wyświetlenia (Newell, Sancha, 1970) powtarzaj dopóki istnieją trójkąty niewyświetlone: { wybierz do wyświetlenia trójkąt dla którego zachodzi jeden z poniższych warunków: zmin > max (zmax) dla wszystkich pozostałych trójkatów wszystkie pozostałe trójkąty leżą po tej jego stronie co obserwator (a), leży po tej stronie każdego z pozostałych trójkątów, która nie zawiera obserwatora (b) jego rzut jest rozłączny z rzutami wszystkich pozostałych trójkątów; jeśli żaden z warunków nie zachodzi dla żadnego trójkąta wybierz ten o największym zmax wyświetl wybrany trójkąt i usuń goz listy pozostałych do wyświetlenia; } (b) (a)
Analiza widoczności Backface culling - wady Bez względu na kryterium sortowania końcowy rezultat będzie zawsze niepoprawny – żaden z trójkątów nie jest całkowicie widoczny a ostatnio wyświetlony będzie zawsze widoczny na obrazie w całości
Obcinanie do obszaru widzenia Projekcji prespektywicznej w okładzie obserwatora można poddawać tylko te fragmenty geometrii, dla których w okładzie obserwatora z >= d (tzn. leżą po tej samej stronie obserwatora co rzutnia Jeśli cały trójkąt (odcinek) leży po niewłaściwej stronie – odrzucamy Jeśli część trójkąta (odcinka) leży po niewłaściwej stronie – przycinamy Przycinamy płaszczyzną obcinającą (ang clipping plane) leżącą przed obserwatorem Ponieważ tworzymy prostokątny obraz rastrowy będący jedynie fragmentem rzutni – wygodniej jest przycinać elementy do obszaru okna obrazu fragment widoczny P1 rzutnia Przednia płaszczyzna obcinająca P’ z =dc fragment obcięty P2 Obserwator w pozycji standardowej
Obcinanie odcinka Dany odcinek o końcach P1= (x1,y1,z1), P2=(x2,y2,z2) Jeśli (z1 > dc) i (z2>dc) – odcinek w całości widoczny Jeśli (z1 < dc) i (z2 < dc) – odcinek w całości niewidoczny Jeśli (z1 > dc) i (z2 < dc) – przycinamy: Zamieniamy P2= (x2,y2,z2) na P’ = (x’2, y’2, z’2) fragment widoczny P1 rzutnia Przednia płaszczyzna obcinająca P’ z =dc fragment obcięty P2 Obserwator w pozycji standardowej
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu nowego końca odcinka w punkcie przecięcia przycinanego odcinka z prostą zawierającą bok okna Jeśli po przycięciu obydwa wierzchołki w oknie - akceptacja Jeśli po przycięciu obydwa końce po niewłaściwej stronie pewnej krawędzi okna – odrzucamy Jeśli żaden z tych przypadków nie zachodzi tniemy odcinek kolejną prostą zawierająca bok okna
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu nowego końca odcinka w punkcie przecięcia przycinanego odcinka z prostą zawierającą bok okna Jeśli po przycięciu obydwa wierzchołki w oknie - akceptacja Jeśli po przycięciu obydwa końce po niewłaściwej stronie pewnej krawędzi okna – odrzucamy Jeśli żaden z tych przypadków nie zachodzi tniemy odcinek kolejną prostą zawierająca bok okna
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu nowego końca odcinka w punkcie przecięcia przycinanego odcinka z prostą zawierającą bok okna Jeśli po przycięciu obydwa wierzchołki w oknie - akceptacja Jeśli po przycięciu obydwa końce po niewłaściwej stronie pewnej krawędzi okna – odrzucamy Jeśli żaden z tych przypadków nie zachodzi tniemy odcinek kolejną prostą zawierająca bok okna
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu nowego końca odcinka w punkcie przecięcia przycinanego odcinka z prostą zawierającą bok okna Jeśli po przycięciu obydwa wierzchołki w oknie - akceptacja Jeśli po przycięciu obydwa końce po niewłaściwej stronie pewnej krawędzi okna – odrzucamy Jeśli żaden z tych przypadków nie zachodzi tniemy odcinek kolejną prostą zawierająca bok okna
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu nowego końca odcinka w punkcie przecięcia przycinanego odcinka z prostą zawierającą bok okna Jeśli po przycięciu obydwa wierzchołki w oknie - akceptacja Jeśli po przycięciu obydwa końce po niewłaściwej stronie pewnej krawędzi okna – odrzucamy Jeśli żaden z tych przypadków nie zachodzi tniemy odcinek kolejną prostą zawierająca bok okna
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu nowego końca odcinka w punkcie przecięcia przycinanego odcinka z prostą zawierającą bok okna Jeśli po przycięciu obydwa wierzchołki w oknie - akceptacja Jeśli po przycięciu obydwa końce po niewłaściwej stronie pewnej krawędzi okna – odrzucamy Jeśli żaden z tych przypadków nie zachodzi tniemy odcinek kolejną prostą zawierająca bok okna Dla obydwu końców odcinka wyznaczamy czterobitowe wektory (bT bB bL bR) określające czy koniec jest po właściwej stronie prostej ( 0 – po właściwej, 1 – po niewłaściwej )
Obcinanie odcinka do rozmiaru okna (Cohen, Sutherland) wylicz wektory B0 i B1 dla końców odcinka P0 i P1; while (true) { if ( (B0 or B1) == (0 0 0 0) ) { akceptuj odcinek (P1 P2); break; } else if ( (B0 and B1) != (0 0 0 0) ) { odrzuć odcinek w całości; break; } { // cięcie if ( B0 != (0 0 0 0) ) b = B0; else b = B1; if ( b[0] ) { // cięcie górną krawędzią okna x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0); y = ymax } if ( b[1] ) { // cięcie dolną krawędzią okna x := x0 + (x1 - x0) * (ymin - y0) / (y1 - y0); y = ymax if ( b[2] ) { // cięcie lewą krawędzią okna y := y0 + (y1 - y0) * (xmin - x0) / (x1 - x0); x = xmin { //ciecie prawą krawędzia okna y := y0 + (y1 - y0) * (xmax - x0) / (x1 - x0); x = xmax } if ( b == B0 ) P0 = (x,y); oblicz B0 P1 = (x,y); Oblicz B1 }
Obcinanie trójkąta do rozmiaru okna Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu boków leżących po różnych stronach prostej zawierającej bok okna Aby przyciąć wielokąt półpłaszczyzną: znajdujemy dwa boki o wierzchołkach po przeciwnej stronie krawędzi półpłaszczyzny, znajdujemy punkty przecięcia tych odcinków w krawędzią odrzucamy wierzchołki po niewłaściwej stronie krawędzi dołączamy do wielokąta dwa nowe wierzchołki
Obcinanie trójkąta do rozmiaru okna Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniiu boków leżących po różnych stronach prostej zawierającej bok okna Aby przyciąć wielokąt półpłaszczyzną: znajdujemy dwa boki o wierzchołkach po przeciwnej stronie krawędzi półpłaszczyzny, znajdujemy punkty przecięcia tych odcinków w krawędzią odrzucamy wierzchołki po niewłaściwej stronie krawędzi dołączamy do wielokąta dwa nowe wierzchołki
Obcinanie trójkąta do rozmiaru okna Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu boków leżących po różnych stronach prostej zawierającej bok okna Aby przyciąć wielokąt półpłaszczyzną: znajdujemy dwa boki o wierzchołkach po przeciwnej stronie krawędzi półpłaszczyzny, znajdujemy punkty przecięcia tych odcinków w krawędzią odrzucamy wierzchołki po niewłaściwej stronie krawędzi dołączamy do wielokąta dwa nowe wierzchołki
Obcinanie trójkąta do rozmiaru okna Przycinamy kolejno odcinek czterema półpłaszczyznami których częścią wspólną jest obszar okna Przycinanie polega na znajdowaniu boków leżących po różnych stronach prostej zawierającej bok okna Aby przyciąć wielokąt półpłaszczyzną: znajdujemy dwa boki o wierzchołkach po przeciwnej stronie krawędzi półpłaszczyzny, znajdujemy punkty przecięcia tych odcinków w krawędzią odrzucamy wierzchołki po niewłaściwej stronie krawędzi dołączamy do wielokąta dwa nowe wierzchołki Otrzymany wielokąt jest zawsze wypukły Ze względu na wypukłość łatwo go striangularyzować
Analiza widoczności Algorytm z Z – buforem (buforem głębokości) 1) Ten fragment jest ostatecznie widoczny w obszarze piksela do którego odległość od obserwatora jest najmniejsza T1 T2 T3 rzutnia z1 z2 z3 < z2 < z1 -> T3 jest widoczny z3 Obserwator w pozycji standardowej
Analiza widoczności Algorytm Z - bufora 0) Metod może być bezpośrednio zastosowana do reprezentacji brzegowej trójkątowej. Inne reprezentacje wymagają wstępnej triangularyzacji 1) Dla każdego piksela obrazu rastrowego zapamiętaj odległość do najblizszego trójkata przetworzonego do tej pory – tablica zawierająca te odległości nazywana jest z-buforem lub buforem głębokości ( ang. depth buffer (z-buffer) ) 2) Wyliczone kolory zapisywane są w buforze koloru (color buffer). Rozdzielczośc obu buforów jest taka sama. 3) Trójkąty modelu sceny przetwarzane są jeden po drugim, w dowolnej kolejności. 4) Dla aktualnie przetwarzanego trójkąta obszar pokrywane przez jego rzut na powierzchnię obrazu jest określany za pomocą metody linii skanowania z interpolacją (omówiona poprzednio) 5) Dla każdego piksela obszaru pokrywanego przez rzut trójkąta atrybuty ( w tym głębokość z) jest określana metodą interpolacji dwuliniowej. 6) Jeśli obliczona głębokość z jest mniejsza niż zapisana w z-buforze, wartości w buforze koloru i z-buforze są zastępowane przez nowe, wyliczone dla wyświetlanego fragmentu
Analiza widoczności Pseudokod algorytmu z-bufora fill depth buffer with infinity value; fill color buffer with background color; for each triangle t in the scene model for each pixel (i,j) of the triangle projection on the image plane; { calculate z coordinate of the triangle fragment visible through pixel (e.g. by using interpolation) if ( z < depth_buffer[i,j] ) depth_buffer[i,j] = z; calculate color c of the fragment at pixel (i,j) by using Gouraud shading – interpolate color directly or by using Phong shading – interpolate normals and caluclate color model; color_buffer[i,j] = c; }
Wyświetlanie scen z powierzchniami przezroczystymi za pomocą algorytmu z-bufora Podstawowy algorytm z-bufora nie przetwarza poprawnie scen z powierzchniami przezroczystymi T1 Jeśli : trójkąty są wyświetlane w kolejności: T3 T2 T1 T1 jest nieprzezroczysty T2 i T3 są przezroczyste to zapis głębokości z dla T3 blokuje wyświetlenie T2 i T1, pomimo, że T1 jest widoczny przez ich przezroczyste powierzchnie T2 T3 rzutnia Obserwator w standardowej pozycji
Wyświetlanie scen z powierzchniami przezroczystymi za pomocą algorytmu z-bufora – podejście dwuprzebiegowe Podziel trójkąty na dwa zbiory: nieprzezroczyste i przezroczyste W pierwszym przebiegu wyświetl trójkąty nieprzezroczyste Wyłącz zapis do z-bufora ale zachowaj test z-bufora Posortuj trójkąty przezroczyste wg odległości od obserwatora w malejącej kolejności Wyświetl trójkąty nieprzezroczyste w tej kolejności T1 T2 T3 projection plane Color of T1 displayed Color of T2 blended with color of T1 Color of T3 blended with color of T1 and T2 observer in standard position Przy wypełnianiu bufora kolory przy wyświetlaniu trójkątów przezroczystych zastosuj mieszanie koloru fragmentu wyświetlanego cT z kolorem cin aktualnie zapisanym w buforze koloru, zastosuj współczynnik przezroczystości kt trójkąta wyświetlanego: cout = kt * cin + cT