Teselacja i uzupełnienia do grafiki Marcin Orchel 1 Wstęp 1.1 Antyaliasing Techniki wygładzania krawędzi, usunięcie zjawiska schodków, postrzępionych krawędzi, aliasingu. Różne techniki. Wielopróbkowanie (multisampling, MSAA), nadpróbkowanie (oversampling, SSAA super-sampling anti-aliasing), filtracja morfologiczna (MLAA, morphological anti-aliasing), FXAA (fast approximate anti-aliasing). 1.1.1 Wielopróbkowanie Wielokrotne próbkowanie. Próbkowanie wszystkich prymitywów wiele razy na każdy piksel. Każdy piksel może być zwizualizowany jako kwadrat. Generujemy wiele próbek w tym kwadracie, a następnie uśredniamy próbki w jeden piksel. Przez kwadrat może przechodzić częściowo renderowany obiekt. Wtedy gdy mamy np. 4 próbki i dwie z nich znajdują sie w renderowanym obiekcie, a pozostałe nie, to piksel będzie miał wartość uśrednioną po tych próbkach. Gdybyśmy natomiast nie mieli wielopróbkowania, to byłaby wzięta wartość piksela jako kolor obiektu lub tła, w zależności od wartości binarnej przechodzenia obiektu przez współrzędne środka piksela. A więc przy wielopróbkowaniu, zapisywany jest kolor dla każdego piksela, który przechodzi choćby częściowo przez renderowany obiekt. Następnie w każdym kwadracie sprawdzane jest czy próbki przechodzą przez renderowany obiekt, te które przechodzą dostają kolor piksela, pozostałe kolor tła. Następnie kolory próbek są uśredniane. Gdy nie używamy wielopróbkowania, wystarczy sprawdzenie czy współrzędne środka piksela przechodzą przez renderowany obiekt. 1.1.2 Nadpróbkowanie Wygenerowanie sceny z teksturami o rozdzielczości dwukrotnie większej niż wielkość okna programu, i uśrednienie wygenerowanych pikseli za pomocą skalowania. Dodatkowo przy skalowaniu można użyć filtrów splotowych, np. filtrów Gaussa, Laplace a. 1.2 Przekształcanie geometrii Przetwarzanie prymitywów. W webgl nie są dostępne shadery geometrii. Shader geometrii jest uruchamiany raz dla każdego prymitywu. 1
1.2.1 Teselacja Dzielenie wielokątów na mniejsze wielokąty. Shadery kontroli teselacji, ewaluacji teselacji, generator prymitywów (teselator). Teselacja używa nowych prymitywów - płatów wierzchołków (patch). Każdy płat składa się z punktów sterujących. W opengl dostępne są podziały triangles - podział trójkątów na mniejsze trójkąty quads - podział czworokątów na trójkąty isolines - podział czworokątów na zbiór linii konturowych - izolinii Podział czworokąta odbywa się w ten sposób, że czworokąt jest dzielony na regularną siatkę czworokątów. Generowane trójkąty muszą pokrywać cały czworokąt i żaden z nich nie może współdzielić pola z innym trójkątem. Przykładowo: mamy kwadrat dzielimy go na siatkę czworokątów np. w ten sposób, że będziemy mieć kolumny i 4 wiersze, a więc parametr gl_tesslevelinner = [, 4]. Następnie dzielimy na trójkąty zewnętrzne komórki. Specyfikujemy podział boków odpowiednio lewego, dolnego, prawego i górnego np. jako gl_tesslevelouter=[1,2,,4]. Jedynka oznacza, że nie dzielimy boku, dwójka oznacza, że będzie jeden punkt podziału, itd. Wierzchołki zewnętrzne łączymy z wierzchołkami wewnętrznymi tak aby powstały trójkąty. Z jednego wierzchołka zewnętrznego może wychodzić kilka krawędzi. Możemy przewidzieć wartości w dowolnym punkcie za pomocą interpolacji liniowej dla 4 wierzchołków czworokąta V = (1 u) (1 v) V 0 + u (1 v) V 1 + uvv 2 + (1 u) vv (1) V i to są wartości, a u i v współrzędne. Mamy wierzchołki V 0 = (0, 0), V 1 = (1, 0), V 2 = (1, 1), V = (0, 1). Mnożymy odległości w kierunku x i y od przeciwnych wierzchołków do punktu (u, v). Jest to ta sama zasada obliczania średniej ważonej jak dla dwóch punktów dla przypadku punktów jednowymiarowych. Gdy te 4 punkty nie będą leżały na jednej płaszczyźnie, to wtedy nie będzie to interpolacja. Alternatywnie moglibyśmy wykonać interpolację dwuliniową. Teselacja trójkątów. Trójkąt dzielimy na zbiór trójkątów. W tym celu rysujemy zewnętrzny trójkąt i rysujemy trójkąt wewnątrz składający się z odpowiedniej liczby punktów tak aby aby proste będące bokami wewnętrznego trójkąta dzieliły na gl_tesslevelinner części. Zauważmy, że gdy ten parametr jest równy 1, trójkąt nie będzie zawierał żadnych wierzchołków wewnątrz. Gdy ten parametr jest równy 2 będzie jeden wierzchołek wewnątrz (trójkąt wewnętrzny zdegenerowany do jednego punktu), dla będą wierzchołki wewnątrz, itd. Jak wyznaczyć punkty wewnętrznego trójkąta? Tak naprawdę dzielimy zewnętrzny trójkąt zgodnie z innerlevel, następnie rysujemy proste prostopadłe w tych punktach podziału, przecięcia dwóch prostych prostopadłych dla wierzchołków sąsiądujących z wierzchołkami zewnętrznego trójkąta definiują wierzchołki wewnętrznego trójkąta. Następnie przecięcia pozostałych prostych prostopadłych z bokami wewnętrznego 2
trojkąta definiują punkty na wewnętrznym trójkącie. Proces powtarzamy dla wewnętrznego trójkąta. Tak naprawdę wyznaczamy wszystkie trójkąty wewnętrzne. Dla inner = 4 mamy jeden wewnętrzny trójkąt i dodatkowo punkt w wewnętrznym trójkącie. Liczba wewnętrznych trójkątów jest równa liczbie inner podzielonej przez 2 i zaokrąglonej w dół. Jeśli to jest liczba parzysta, to najbardziej wewnętrzny trójkąt będzie pojedynczym wierzchołkiem. Następnie pozostawiamy wierzchołki oprócz najbardziej zewnętrznego trójkąta i usuwamy wszystkie linie, oprócz linii definiujących trójkąty. Drugi parametr gl_tesslevelouter dla każdej ze ścian trójkąta zewnętrznego określa liczbę podziałów tej ściany, dla 2 oznacza, że będzie podział na 2 części. Następnie łączymy powstałe wierzchołki na tej krawędzi z wierzchołkami wewnętrznymi. Podczas łączenia musi być spełniona zasada, że te wierzchołki, które były bezpośrednio połączone w pierwszym etapie algorytmu będą połączone również teraz (wierzchołków zewnętrznych już nie ma, chyba, że inner jest równe outer, każdy wierzchołek trójkąta wewnętrznego miał dwa korespondujące wierzchołki zewnętrznego trójkąta, a pozostałe po jednym). Pozostałe krawędzie zależą od implementacji. Przykładowo mamy trójkąt o wierzchołkach (0, 0, 1), (1, 0, 0), (0, 1, 0). W shaderze ewaluacji teselacji możemy zastosować interpolację liniową dla nowo powstałych wierzchołków. Gdy mamy dane współrzędne barycentryczne punktu wewnątrz trójkąta (u, v, w), gdzie w = 1 u v, to wykonujemy interpolację liniową dla jakiegoś atrybutu zdefiniowanego dla każdego wierzchołka (V 0, V 1, V 2 ) za pomocą wzoru V = uv 0 + vv 1 + wv 2 (2) Teselacja czworokątów na odcinki, podobnie jak teselacja trójkątów. Dzielimy boki zewnętrzne wg parametru gl_tesslevelinner[0] dzieli linie horyzontalne, a gl_tesslevelinner[1] dzieli linie wertykalne. Powstają nam punkty na zewnętrznym czworkącie. Następnie dla każdego wierzchołka tego czworokąta, prowadzimy prostopadłe w wierzchołkach sąsiadujących, ich przecięcie utworzy wierzchołek wewnętrznego czworokąta. Łączymy wierzchołki wewnętrznego czworokąta. Następnie prowadzimy prostopadłe z pozostałych wierzchołków. Ich przecięcie z bokami wewnętrznego trójkąta definiuje pozostałe wierzchołki leżące na wewnętrznym czworokącie. Procedurę powtarzamy dla wewnętrznego czworkąta. Najbardziej zewnętrzny czworokąt będzie albo czworokątem albo czworkątem zdegenerowanym do linii lub punktu. Następnie usuwamy wszystkie punkty na czworokącie zewnętrznym i go ponownie dzielimy wg parametru gl_tesslevelouter[]. Następnie dzielimy obszar na trójkąty, podobnie jak dla trójkąta. Podział na izolinie kwadratu. Tworzymy horyzontalne odcinki, liczba odcinków to gl_tesslevelouter[0]. Każdy odcinek składa się z segmentów o tej samej długości, liczba segmentów określona jest przez parametr gl_tesslevelouter[1]. Górna krawędź kwadratu jest pomijana. Domyślny podział krawędzi na równe części w teselacji to equal_spacing. Problemem jest skokowa zmiana teselacji, bo mamy podział na całkowitą liczbę części. W fractional_even_spacing i fractional_odd_spacing segmenty mogą nie mieć tych samych długości. Zaokrąglenie współczynnika teselacji do mniejszej liczby parzystej lub
nieparzystej odpowiednio. Algorytm PN Triangles (curved point-normal triangles). Umożliwia wprowadzanie wypukłości do podziału na trójkąty. Trójkąty po podziale nie będą leżały na płaszczyźnie oryginalnego trójkąta. Wykorzystanie trójkątnych płatów powierzchni Beziera do interpolacji współrzędnych wierzchołków i współrzędnych wektorów normalnych. Mamy dane wierzchołki trójkąta i dla każdego wierzchołka wektor normalny. Interpolacja sześcienna do współrzędnych wierzchołków, interpolacja kwadratowa do współrzędnych wektorów normalnych, dla pozostałych atrybutów interpolacja liniowa przy użyciu współrzędnych barycentrycznych trójkąta. Interpolacja sześcienna współrzędnych wierzchołków za pomocą trójkąta Beziera f (u, v, w) = i+j+k= b ijk! i!j!k! ui v j w k () gdzie b ijk to współrzędne punktów kontrolnych, b 00, b 00, b 00 to współrzędne wierzchołków dzielonego trójkąta, b 210, b 120, b 021, b 021, b 102, b 201 to współrzędne punktów po podziale każdej krawędzi na części, a b 111 to współrzędne punktu centralnego trójkąta, (u, v, w) to współrzędne barycentryczne dowolnego punktu, zwracane są współrzędne trójwymiarowe punktu powierzchni Beziera. Dla współrzędnych barycentrycznych f (u, v, w) = b 00 w + b 00 u + b 00 v + b 210 w 2 u + b 120 wu 2 + b 201 w 2 v + b 021 u 2 v (4) Współrzędne punktów kontrolnych to + b 102 wv 2 u + b 012 uv 2 + 6b 111 wuv (5) b 00 = V 0 (6) b 00 = V 1 (7) b 00 = V 2 (8) b 210 = 2V 0 + V 1 w 01 N0 b 120 = 2V 1 + V 0 w 10 N1 b 021 = 2V 1 + V 2 w 12 N1 b 012 = 2V 2 + V 1 w 21 N2 b 102 = 2V 2 + V 0 w 20 N2 b 201 = 2V 0 + V 2 w 02 N0 (9) (10) (11) (12) (1) (14) 4
b 111 = b 210 + b 120 + b 021 + b 012 + b 102 + b 201 4 V 0+V 1 +V 2 6 gdzie w ij = (V j V i ) N i, N i to współrzędne wektora normalnego dla i-tego wierzchołka. Wzory polegają na tym, że każda krawędź dzielona jest na równe części za pomocą dwóch punktów pośrednich. Każdy punkt pośredni jest rzutowany na płaszczyznę styczną w najbliższym wierzchołku. Ostatni punkt kontrolny to średnia wszystkich poprzednich punktów po rzutowaniu. Rzutowanie na płaszczyznę styczną punktu Q to punkt Q taki, że (15) Q = Q w N (16) gdzie w = (Q P ) N. A więc rzutowanie np. punktu Q = (2V 1 + V 0 )/ będzie wynosiło 2V 1 + V 0 ( ) 2V1 + V 0 V 1 N 1 = 2V 1 + V ( 0 (V 0 V 1 ) N ) N1 1 = b 120 (17) Interpolacja współrzędnych wektorów normalnych n (u, v, w) = n ijk u i v j w k (18) i+j+k= gdzie n ijk to wartości w punktach kontrolnych (wierzchołki i środki krawędzi). Dla współrzędnych barycentrycznych n (u, v, w) = n 200 w 2 + n 020 u 2 + n 002 v 2 + n 110 wu + n 001 uv + n 101 wv (19) gdzie wartości wynoszą n 200 = N 0 (20) n 020 = N 1 (21) n 002 = N 2 (22) n 110 = N 0 + N 1 v 01 (V 1 V 0 ) N 0 + N 1 v 01 (V 1 V 0 ) n 001 = N 1 + N 2 v 12 (V 2 V 1 ) N 1 + N 2 v 12 (V 2 V 1 ) n 101 = N 2 + N 1 v 20 (V 0 V 2 ) N 2 + N 1 v 20 (V 0 V 2 ) Teselacja Phonga. Mamy wierzchołki trójkąta i wektory normalne w każdym z wierzchołków. Rzutujemy bazowy trójkąt na płaszczyzny styczne w wierzchołkach trójkąta określone przez wektory normalne. Otrzymujemy trójkąty. Rzutujemy dany punkt na każdą z tych płaszczyzn. Dla dowolnego punktu danego we współrzędnych barycentrycznych mnożymy go przez macierz współrzędnych punktów po zrzutowaniu. Rzuty punktu P na płaszczyzny styczne ( π i (P ) = P (P V i ) N ) Ni i (26) 5 (2) (24) (25)
( π j (P ) = P (P V j ) N ) Nj j (27) ( π k (P ) = P (P V k ) N ) Nk k (28) Współrzędne punktu P po teselacji to π i (P ) P (u, v, w) = [u, v, w] π j (P ) (29) π k (P ) Postać wielomianowa P (u, v, w) = u 2 P i + v 2 P j + w 2 P k + uv (π i (P j ) + π j (P j )) + vw (π j (P k ) + π k (P j )) (0) + wu (π k (P i ) + π i (P k )) (1) Dodatkowo wprowadza się liniową interpolację między teselacją liniową a teselacją Phonga P i π i (P ) P α (u, v, w) = (1 α) [u, v, w] P j + α [u, v, w] π j (P ) (2) π k (P ) Współrzędne wektorów normalnych obliczane są przy pomocy teselacji liniowej. 1. Krzywe i powierzchnie parametryczne 1..1 Krzywa Beziera Krzywe parametryczne, gdzie parametr t przyjmuje wartości [0, 1]. Kształt krzywej określony jest przez punkty kontrolne. Krzywa przechodzi przez pierwszy i ostatni punkt kontrolny. Przykładowo mamy krzywą Beziera z punktami sterującymi, krzywa przechodzi przez punkt A i C. Aby wyznaczyć krzywą Beziera łączymy punkt A z B i punkt C z B. Stosujemy dwukrotnie interpolację liniową w postaci parametrycznej o parametrze t [0, 1] P = (1 t) A + tb () Dla odcinka AB otrzymamy punkt D Dla odcinka BC otrzymamy punkt E P k D = A + t (B A) (4) E = B + t (C B) (5) Następnie jest robiona interpolacja z tym samym parametrem t dla punktów D i E P = D + t (E D) (6) 6
Po podstawieniu otrzymujemy P = A + t (B A) + t (B + t (C B) A t (B A)) (7) P = A + t (B A) + tb + t 2 (C B) ta t 2 (B A) (8) P = A + t (B A + B A) + t 2 (C B B + A) (9) P = A + 2t (B A) + t 2 (C 2B + A) (40) Otrzymaliśmy równanie kwadratowe ze względu na t. Jest to krzywa Beziera drugiego stopnia. Sposób wyznaczania punktu P to algorytm de Casteljau. Gdy podstawiamy różne wartości t otrzymujemy różne punkty krzywej Beziera. Krzywe Beziera trzeciego stopnia z 4 punktami kontrolnymi. Dodajemy jeden punkt. A więc krzywa przechodzi przez punkty A i D. Schemat postępowania jest podobny. Tworzymy linie AB, BC i CD. Po interpolacji liniowej otrzymujemy punkty E, F, G odpowiednio. Tworzymy linie EF i FG. Interpolujemy wzdłuż tych linii i otrzymujemy punkty H i I i na samym końcu wykonujemy interpolację między H i I i otrzymujemy P E = A + t (B A) (41) F = B + t (C B) (42) G = C + t (D C) (4) H = E + t (F E) (44) I = F + t (G F ) (45) P = H + t (I H) (46) Zauważmy, że interpolacja punktu P jest obliczana za pomocą krzywej Beziera drugiego stopnia (punkty E, F, G). Po podstawieniu otrzymalibyśmy równanie sześcienne dla t. Jest to krzywa Beziera trzeciego stopnia. Równanie parametryczne z algorytmu de Casteljau to P (t) = P 0 (1 t) + P 1 t (1 t) 2 + P 2 t 2 (1 t) + P t (47) W postaci macierzowej 1 1 P 0 [ ] P (t) = t t 2 6 0 P t 1 1 0 0 P 2 1 0 0 0 P (48) Możemy również tworzyć splajny z krzywych Beziera. Np. możemy połączyć krzywe Beziera stopnia (krzywa przechodzi przez 4 punkty). Krzywe takie mają nazwę krzywe B-sklejane (cubic B-spline). Wtedy t ma wartości z przedziału [0, ]. Możemy zdefiniować warunki z pochodnymi tak aby otrzymać funkcję różniczkowalną. Jest to krzywa Hermite a. 7
1..2 Powierzchnie Beziera Mamy dwa parametry u, v z przedziału [0, 1]. Odpowiednik trójwymiarowy krzywych Beziera. Dla płatów powierzchni trzeciego stopnia mamy 16 punktów kontrolnych/sterujących. W szczególnym przypadku punkty sterujące mogą być położone na jednej płaszczyźnie na siatce równo ułożone. Powierzchnia przechodzi przez 4 punkty graniczne (wierzchołki siatki). Traktujemy każde 4 punkty w wierszu siatki jako punkty sterujące krzywej Beziera trzeciego stopnia. Dla siatki 4x4 mamy 4 krzywe. Po interpolacji wzdłuż każdej krzywej z parametrem t 0 otrzymamy 4 nowe punkty. Dla utworzonych 4 nowych punktów tworzymy znowu krzywą Beziera. Interpolacja wzdłuż drugiej krzywej za pomocą nowej wartości t 1 daje kolejny punkt płata. Równanie dla powierzchni Beziera to m n P (u, v) = B m,i (u) B n,j (v) p ij (49) i=0 j=0 gdzie p ij to punkty siatki. Możemy to zapisać jako m n P (u, v) = B m,i (u) B n,j (v) p ij (50) i=0 Zdefiniujmy n q i (v) = B n,j (v) p ij (51) j=0 po podstawieniu m P (u, v) = B m,i (u) q i (v) (52) i=0 P (u, v) jest punktem na krzywej Beziera zdefiniowanej przez m+1 punktów kontrolnych q 0 (v), q 1 (v),..., q m (v). Każde q i (v) jest punktem na krzywej Beziera zdefiniowanej za pomocą i-tego wiersza punktów kontrolnych: p i0, p i1,..., p in. Krawędzie płatu tworzą krzywą Beziera opisaną przez brzegowe punkty kontrolne. Współrzędne powierzchni Beziera u T T 1 1 P 0,0 P 0,1 P 0,2 P 0, 1 1 v u P (u, v) = 2 6 0 P 1,0 P 1,1 P 1,2 P 1, 6 0 v 2 u 0 0 P 2,0 P 2,1 P 2,2 P 2, 0 0 v 1 1 0 0 0 P,0 P,1 P,2 P, 1 0 0 0 1 (5) Równania macierzowe pozwalają na wyznaczenie wektorów normalnych za pomocą iloczynu wektorowego wektora stycznego i wektora binormalnego u T T 1 1 P 0,0 P 0,1 P 0,2 P 0, 1 1 v 2 P (u, v) u T = = 2 6 0 P 1,0 P 1,1 P 1,2 P 1, 6 0 2v v u 0 0 P 2,0 P 2,1 P 2,2 P 2, 0 0 1 1 1 0 0 0 P,0 P,1 P,2 P, 1 0 0 0 0 (54) 8 j=0
P (u, v) B = = u 1.. Kwadryki u 2 T T 1 1 P 0,0 P 0,1 P 0,2 P 0, 1 1 v 2u 6 0 P 1,0 P 1,1 P 1,2 P 1, 6 0 v 2 1 0 0 P 2,0 P 2,1 P 2,2 P 2, 0 0 v 0 1 0 0 0 P,0 P,1 P,2 P, 1 0 0 0 1 (55) Powierzchnie drugiego stopnia o równaniu a 11 x 2 + a 22 y 2 + a z 2 + 2a 12 xy + 2a 2 yz + 2a 1 zx + 2a 14 x + 2a 24 y + 2a 2 z + a 44 = 0 (56) Elipsoida, sfera, paraboloida, hiperboloida. Elipsoida. Równanie kanoniczne x 2 a 2 + y2 b 2 + z2 c 2 = 1 (57) gdzie a, b, c to długości półosi elipsoidy. Równanie parametryczne x = a sin φ cos θ (58) y = b sin φ sin θ (59) z = c sin φ (60) gdzie φ [0, 2π], θ [0, π]. Wektory normalne tworzymy za pomocą iloczynu wektorowego wektora stycznego i binormalnego T a cos φ cos θ = b cos φ sin θ (61) c cos φ a sin φ sin θ B = b sin φ cos θ (62) 0 Alternatywnie dla równania kanonicznego x a N = y b (6) z c 9
1..4 Krzywa Kocha Wyjściowym prymitywem jest trójkąt równoboczny. Każdy bok trójkąta dzielimy na równe odcinki, a środkową część zastępują dwa odcinki o takiej samej długości, nachylone względem boku tak, aby wraz z wyciętym fragmentem tworzyły trójkąt równoboczny. Obraz Mandelbrota. Iteracje Z n = Z 2 n 1 + C (64) Działanie wykonuje się do momentu gdy Z przekroczy zdefiniowany próg lub osiągnie się określoną liczbę iteracji. Gdy liczba iteracji osiągnie poziom max_iterations to oznacza, że punkt znajduje się wewnątrz zbioru i jest kolorowany na czarno. W przeciwnym razie punkt znajdzie się poza zbiorem z liczbą iteracji mniejszą od max_iterations. Mamy więc numer iteracji ostatniej, możemy więc zdefiniować kolor jako kolor teksela dla danej tekstury jednowymiarowej o współrzędnej iterations max_iterations Na początku Z = (0 + 0i), C to współrzędne punktu na którym są prowadzone iteracje. Zbiór Julii. Podobny wzór jak w zbiorze Mandelbrota, ale to Z otrzymuje współrzędne punktu, na którym przeprowadzamy obliczenia, C to stała zależna od aplikacji. Mamy nieskończenie wiele zbiorów Julii po jednym dla każdej wartości C. Wzór na kwadrat liczby zespolonej (65) z 2 = (x 2 y 2 ) + i(2xy) (66) Próg jest liczony jako iloczyn skalarny wektora z z samym sobą, więc mamy podniesioną do kwadratu część rzeczywistą i urojoną i dodane do siebie. Jesli liczba iteracji osiągnęła poziom max_iterations kolor będzie czarny, w przeciwny razie 2 Zadania 2.1 Zadania na zajęcia przetestować antialiasing msaa, ssaa. Zaobserwować gładsze linie, redukcję postrzępienia Wskazówki do Three.js w edytorze threejs https://threejs.org/editor/ dodać obiekt do sceny, w zakładce Project, przetestować dwie opcje z włączonym antialiasingiem lub wyłączonym, zaobserwować różnice parametr antialias https://threejs.org/docs/#api/renderers/webglrenderer https://threejs.org/examples/webgl_postprocessing_ssaa_unbiased. html 10
https://threejs.org/examples/webgl_postprocessing_ssaa.html https://threejs.org/examples/webgl_postprocessing_taa.html Wskazówki do WebGL parametr antialias https://developer.mozilla.org/en-us/docs/web/api/ HTMLCanvasElement/getContext ustawienie w about:config webgl.msaa-force na true https://developer.mozilla.org/en-us/docs/web/api/webgl2renderingcontext/ renderbufferstoragemultisample http://webglsamples.org/webgl2samples/#fbo_multisample Wskazówki do OpenGL https://www.khronos.org/opengl/wiki/multisampling https://learnopengl.com/#!advanced-opengl/anti-aliasing przetestować teselację, przerobić program tak aby pokazywał teselację dla pojedynczego kwadratu, trójkąta na trójkąty Wskazówki do Three.js https://threejs.org/examples/webgl_modifier_tessellation.html http://www.realtimerendering.com/erich/udacity/exercises/unit_tessellation_ demo.html https://threejs.org/examples/#webgl_geometry_teapot Wskazówki do webgl zaznaczyć showpoints http://www.madpaw.com/ce01/ http://stackoverflow.com/questions/1290128/webgl-and-tessellationlibrary Wskazówki do OpenGL WskazówkidoOpenGL Wskazówki https://www.youtube.com/watch?v=kct5fwuotz8 przetestować teselację PN Triangles Wskazówki do C++ zobaczyć jak wygląda siatka http://codeflow.org/entries/2010/nov/07/ opengl-4-tessellation/ 11
https://github.com/jdupuy/tesscomp01/zipball/master przetestować teselację Phonga Wskazówki http://onrendering.blogspot.com/2011/12/tessellation-on-gpu-curvedpn-triangles.html http://perso.telecom-paristech.fr/~boubek/papers/phongtessellation/ https://www.youtube.com/watch?v=pmv9v9mdnuc przetestowac krzywe Beziera Wskazówki do Three.js https://threejs.org/docs/#api/extras/curves/cubicbeziercurve Wskazówki do WebGL http://kibotu.net/webgl/cg2/cg2-a01.2-1./index.html przetestować powierzchnie Beziera, zdefiniować podstawowe obiekty za pomocą ścieżek Beziera, przetestować trójkąty Beziera Wskazówki do three.js https://github.com/dsitum/bezier-surface Wskazówki do webgl http://vladamakaric.github.io/interactivebeziersurface/ Przetestować kwadryki, elipsoidę Wskazówki do three.js http://jsfiddle.net/salixalba/n1hjm5n/ http://jsfiddle.net/k7pxyl2/ http://www.smartjava.org/ltjs/chapter-05/08-basic-d-geometriestorus-knot.html http://www.smartjava.org/ltjs/chapter-05/06-basic-d-geometriescylinder.html http://www.smartjava.org/ltjs/chapter-05/09-basic-d-geometriespolyhedron.html http://www.smartjava.org/ltjs/chapter-05/07-basic-d-geometriestorus.html http://www.smartjava.org/ltjs/chapter-05/05-basic-d-geometriessphere.html 12
http://www.smartjava.org/ltjs/chapter-05/04-basic-d-geometriescube.html http://www.myjscode.com/demo/threejs/chapter-05/01-basic-2d-geometriesplane.html http://www.myjscode.com/demo/threejs/chapter-05/0-basic-d-geometriesring.html http://www.myjscode.com/demo/threejs/chapter-05/ https://wowmoron.wordpress.com/201/10/21/webgl-and-javascript-drawingsimple-d-shapes-using-three-js/ Przetestować krzywą Kocha, fraktal Julii, fraktal Mandelbrota. Dla fraktali Julii zmieniać parametr C i maksymalną liczbę iteracji Wskazówki do three.js https://www.shadertoy.com/view/xslgzl Wskazówki do webgl animowany fraktal Julii http://www.ibiblio.org/e-notes/webgl/makin. html https://www.shadertoy.com/view/ldcsrx https://jsfiddle.net/mcjohnalds45/jghl52d/ https://www.shadertoy.com/view/mlfrx http://hirnsohle.de/test/fractallab/ 2.2 Zadania dodatkowe 2. Zadania dodatkowe do C++ Wskazówki 2.4 Zadania domowe na plusa zadania znajdują sie w moodle 1