1 DirectX Cell Shading

Podobne dokumenty
OpenGL : Oświetlenie. mgr inż. Michał Chwesiuk mgr inż. Tomasz Sergej inż. Patryk Piotrowski. Szczecin, r 1/23

Oświetlenie obiektów 3D

Grafika Komputerowa Wykład 5. Potok Renderowania Oświetlenie. mgr inż. Michał Chwesiuk 1/38

g_pd3ddevice->createpixelshader( (DWORD*)pCode->GetBufferPointer(), &PixelShader ); pcode->release();

Gry Komputerowe Laboratorium 4. Teksturowanie Kolizje obiektów z otoczeniem. mgr inż. Michał Chwesiuk 1/29. Szczecin, r

Grafika Komputerowa Wykład 6. Teksturowanie. mgr inż. Michał Chwesiuk 1/23

Plan wykładu. Akcelerator 3D Potok graficzny

Oświetlenie. Modelowanie oświetlenia sceny 3D. Algorytmy cieniowania.

RENDERING W CZASIE RZECZYWISTYM. Michał Radziszewski

Programowanie gier komputerowych Tomasz Martyn Wykład 6. Materiały informacje podstawowe

Modelowanie i wstęp do druku 3D Wykład 1. Robert Banasiak

1. Prymitywy graficzne

1 Matematyka Macierze

GRK 4. dr Wojciech Palubicki

1 Temat: Vertex Shader

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Animowana grafika 3D. Opracowanie: J. Kęsik.

Model oświetlenia. Radosław Mantiuk. Wydział Informatyki Zachodniopomorski Uniwersytet Technologiczny w Szczecinie

O co chodzi z tym MATLAB'em?!

Tajemnice koloru, część 1

Co to jest niewiadoma? Co to są liczby ujemne?

1 DirectX Vertex shader 1

Grafika 3D program POV-Ray - 1 -

Jak tworzyć dobre wizualizacje? Porady do wykorzystania w programie KD Max. MTpartner s.c.

Lekcja : Tablice + pętle

Zadanie polega na zbudowaniu i wyświetleniu przykładowej animowanej sceny przedstawiającej robota spawalniczego typu PUMA.

KMO2D. Kolizje między-obiektowe w 2D

Systemy wirtualnej rzeczywistości. Podstawy grafiki 3D

Implementacja filtru Canny ego

Transformacje. dr Radosław Matusik. radmat

OpenGL Światło (cieniowanie)

2 Matematyka Wektory. A = ( Ax, Ay, Az ) - początek wektora B = ( Bx, By, Bz ) - koniec wektora, więc

Matlab, zajęcia 3. Jeszcze jeden przykład metoda eliminacji Gaussa dla macierzy 3 na 3

Synteza i obróbka obrazu. Tekstury. Opracowanie: dr inż. Grzegorz Szwoch Politechnika Gdańska Katedra Systemów Multimedialnych

Priorytet Przysłony. Angielska nazwa dzisiejszego trybu kreatywnego pochodzi od słowa APERATURE czyli PRZYSŁONA.

Bartłomiej Filipek

GRK 5. dr Wojciech Palubicki

Zadanie 1. Ściana. 1. Potrzebne zmienne w dołączonym do zadania kodzie źródłowym

Laboratorium grafiki komputerowej i animacji. Ćwiczenie V - Biblioteka OpenGL - oświetlenie sceny

Karty graficzne możemy podzielić na:

Lista 6. Kamil Matuszewski 13 kwietnia D n =

1 Matematyka Transformacje

Rachunek wektorowy - wprowadzenie. dr inż. Romuald Kędzierski

rgbf<składowa_r,składowa_g,składowa_b,filter>. Dla parametru filter przyjmij kolejno wartości: 0.60, 0.70, 0.80, 0.90, 1.00, np.:

Oświetlenie w OpenGL. Oprogramowanie i wykorzystanie stacji roboczych. Wykład 8. Światło otaczajace. Światło rozproszone.

Przykłady zastosowań funkcji tekstowych w arkuszu kalkulacyjnym

2 Przygotował: mgr inż. Maciej Lasota

OpenGL Światło (cieniowanie)

Adobe InDesign lab. 3 Jacek Wiślicki,

Scena 3D. Cieniowanie (ang. Shading) Scena 3D - Materia" Obliczenie koloru powierzchni (ang. Lighting)

1 DirectX Piel shader 1

OpenGL oświetlenie. Bogdan Kreczmer. Katedra Cybernetyki i Robotyki Wydziału Elektroniki Politechnika Wrocławska

Geometria Lista 0 Zadanie 1

Ćwiczenie 4 - Podstawy materiałów i tekstur. Renderowanie obrazu i animacji

CorelDRAW. 1. Rysunek rastrowy a wektorowy. 2. Opis okna programu

Celem tego projektu jest stworzenie

Co to jest wektor? Jest to obiekt posiadający: moduł (długość), kierunek wraz ze zwrotem.

Podstawy działań na wektorach - dodawanie

WZAJEMNY SZACUNEK DLA WSZYSTKICH CZŁONKÓW RODZINY JAKO FUNDAMENT TOLERANCJI WOBEC INNYCH

Mapowanie sześcienne otoczenia (cubic environment mapping)

Najprostsze z zadań z prawdopodobieństwa robi się korzystając z dystrybuanty. Zacznijmy od tego - tu mamy rozkład (wyniki pomiarów):

Równania miłości. autor: Tomasz Grębski

3. Macierze i Układy Równań Liniowych

Mamy co prawda trawiastą powierzchnię ziemi i niebo, ale scena wygląda mało realistycznie. Zmieńmy nieco właściwości tekstury płaszczyzny gruntu:

Misja#3. Robimy film animowany.

Przetwarzanie grafiki rastrowej na wektorową

Systemy wirtualnej rzeczywistości. Komponenty i serwisy

Rys 3-1. Rysunek wałka

Wykład 4. Rendering (1) Informacje podstawowe

WEKTORY I MACIERZE. Strona 1 z 11. Lekcja 7.

4. Rysowanie krzywych

#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ D3DFVF_DIFFUSE D3DFVF_TEX1 )

FUNKCJA KWADRATOWA. Zad 1 Przedstaw funkcję kwadratową w postaci ogólnej. Postać ogólna funkcji kwadratowej to: y = ax + bx + c;(

Uwagi ogólne. 3. Użycie gwiazdki zamiast kropki na oznaczenie mnożenia: 4. Lepiej niż 6, F wyglądałby zapis: 69,539 pf.

GRK 5. dr Wojciech Palubicki

Definiowanie układu - czyli lekcja 1.

5. OKREŚLANIE WARTOŚCI LOGICZNEJ ZDAŃ ZŁOŻONYCH

CIĄGI wiadomości podstawowe

Przetwarzanie obrazów wykład 4

Elementy geometrii analitycznej w R 3

Rzutowanie z 4D na 3D

Animowana grafika 3D Laboratorium 3

Grafika komputerowa ZS Sieniawa Andrzej Pokrywka. Ścieżki cz. 2. Rysunki z kreskówek. Autor: Joshua Koudys

WYBUCHAJĄCE KROPKI ROZDZIAŁ 1 MASZYNY

Analiza moż liwości i porównanie nowych ję zyków do programowania grafiki

Zadeklarowanie tablicy przypomina analogiczną operację dla zwykłych (skalarnych) zmiennych. Może zatem wyglądać na przykład tak:

Bartosz Bazyluk POTOK RENDEROWANIA Etapy renderowania w grafice czasu rzeczywistego. Grafika Komputerowa, Informatyka, I Rok

Gry komputerowe, Informatyka N1, III Rok

to jest właśnie to, co nazywamy procesem życia, doświadczenie, mądrość, wyciąganie konsekwencji, wyciąganie wniosków.

Grafika Komputerowa Wykład 4. Synteza grafiki 3D. mgr inż. Michał Chwesiuk 1/30

GRAFIKA CZASU RZECZYWISTEGO Wprowadzenie do OpenGL

Copyright 2015 Monika Górska

SMOP - wykład. Rozkład normalny zasady przenoszenia błędów. Ewa Pawelec

Tekstury Ćwiczenie 1 (Kostka)

Transkrypcja wideo: Czym są środki trwałe i jak je rozliczać? Q&A

0 + 0 = 0, = 1, = 1, = 0.

Grafika komputerowa. Dla DSI II

2. Układy równań liniowych

Informatyka II. Laboratorium Aplikacja okienkowa

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

Transkrypt:

1 DirectX Cell Shading Po lekcji teoretycznej czas pokazać, co możemy zrobić w praktyce. Jak już wiemy tak naprawdę cieniowanie kreskówkowe nie stanowi wielkiego problemu i cały ambaras polega w zasadzie na odpowiednim przygotowaniu tekstur, których użyjemy w przykładzie. Żeby za dużo nie kombinować oprzemy się na tych, z lekcji teoretcznej. Co do samego kodu to w zasadzie dwie główne rzeczy będą nam potrzebne - a mianowicie odpowiednia struktura wierzchołka i vertex shader, który policzy co trzeba. W cieniowaniu kreskówkowym w zasadzie nie używa się tekstur - przynajmniej darmo wypatrywać czegoś podobnego w znanych komiksach czy bajkach rysunkowych. My aby sobie nie zaciemniać przykładu także ograniczymy się tylko do mechanizmu samego cieniowania i nadawania bryłom konturów. A tekstury przecież możecie nałożyć sobie sami, bo robiliśmy to już chyba dziesiątki razy. A więc po pierwsze struktura wierzchołka: struct SVertex float x, y, z; // position float nx, ny, nz; // normal float u1, v1; // firts texture channel float u2, v2; // second texture channel ; Oczywiście pozycja, normalna która tutaj okaże się niezbędna (w końcu wyliczamy oświetlenie) no i dwa zestawy współrzędnych tekstur - jeden dla tekstury cieniującej a drugi dla tekstury definiującej kontury obiektu. Tak naprawdę to wszystko jest dla nas już w tym momencie zupełnym banałem, więc nawet nie powinienem tego opisywać, no ale dla porządku niech wam będzie. Inicjalizację urządzenia, ładowanie geometrii i tekstur także pomijamy, bo mamy ważniejsze sprawy - a mianowicie druga decydująca w naszym przykładzie sprawa, czyli vertex shader: vs.1.1 dcl_position dcl_normal dcl_texcoord0 dcl_texcoord1 v0 v3 v7 v8 ; c0-c3 - world transform matrix ; c4-c7 - view*proj transform matrix ; c8 - eye position ; c9 - light vector def c10, 0.0f, 1.0f, 0.0f, 0.0f ; position to world dp4 r0.x, v0, c0 dp4 r0.y, v0, c1 dp4 r0.z, v0, c2 dp4 r0.w, v0, c3 ; and final dp4 opos.x, r0, c4 dp4 opos.y, r0, c5 dp4 opos.z, r0, c6 dp4 opos.w, r0, c7 ; normal to world dp3 r1.x, v3, c0 dp3 r1.y, v3, c1 dp3 r1.z, v3, c2 ; normalize normal dp3 r1.w, r1, r1 rsq r1.w, r1.w mul r1, r1, r1.w ; output color mov od0, c10 ; and toon textures dp3 ot0.x, r1,-c9 ; eye vector sub r2, c8, r0

2 DirectX Cell Shading dp3 r2.w, r2, r2 rsq r2.w, r2.w mul r2, r2, r2.w ; outline texture dp3 ot1.x, r1, r2 Jak widać shader nie jest trudny bo i być nie może. Dla zasady jednak postarajmy sobie zobaczyć poszczególne kawałki, żeby w razie wątpliwości nie stresować się. ; position to world... dp4 r0.x, v0, c0 dp4 r0.y, v0, c1 dp4 r0.z, v0, c2 dp4 r0.w, v0, c3 Najpierw oczywiście manewrujemy naszym obiektem w świecie, czyli mnożymy pozycję wejściową wierzchołka poprzez macierz świata umieszczoną w rejestrach c0 do c3. Wynik zostawiamy w rejestrze r0, ponieważ jeszcze się nam przyda. ;...and final dp4 opos.x, r0, c4 dp4 opos.y, r0, c5 dp4 opos.z, r0, c6 dp4 opos.w, r0, c7 Żeby jednak za dużo nie mieszać od razu też wyślemy nasz wierzchołek na ekran, czyli przepuszczamy przez przemnożone przez siebie macierze widoku i projekcji, co w sumie wrzuci nam go na ekran. ; normal to world dp3 r1.x, v3, c0 dp3 r1.y, v3, c1 dp3 r1.z, v3, c2 Oczywiście, żeby policzyć oświetlenie podczas manewrowania obiektem po scenie musimy także manewrować normalnymi wierzchołków, które muszą pokonać dokładnie tę samą drogę co wierzchołki. Normalne zapamiętujemy jak zwykle już w rejestrze tymczasowym r2. ; normalize normal dp3 r1.w, r1, r1 rsq r1.w, r1.w mul r1, r1, r1.w I robimy oczywiście bardzo ważny manewr, o którym nigdy nie powinniśmy zapominać - czyli normalizujemy wszelkie wektory przed obliczeniami oświetlenia. mov od0, c10 Do wyjściwoego rejestru koloru wysyłamy jakiś dobrany przez nas kolor diffuse obiektu, ponieważ akurat w tym przypadku nie zajmujemy się materiałami wczytanymi bezpośrednio z modelu, no ale przecież nie w tym rzecz. W tym przykładzie wymyśliłem sobie obiekt zielony, ale możecie sobie zdefiniować jaki chcecie tak naprawdę. Jak ktoś będzie robił finalną aplikację to oczywiście musi sobie opracować mechanizm wysyłania kolorów materiałów przez stałe shadera. ; and toon textures dp3 ot0.x, r1,-c9 Teraz nastąpi właściwy bajer w naszym przykładzie czyli pocieniowanie naszego obiektu za pomocą tekstur. Jak widać powyżej, w kolorze diffuse nie zawieramy żadnej warotści wyliczonej na podstawie normalnej obiektu a jedynie stałą wartość koloru. Gdybyśy nie pocieniowali obiektu w inny sposób to dostalibyśmy na ekranie coś zupełnie bez wyrazu i głębi. W rejestrze c9 wpada do shadera wektor światła znajdującego się na scenie. Odwracamy go (za pomocą znaku "-") aby móc wyliczyć własćiwą warość iloczynu skalarnego pomiędzy nim a normalną. Minus jest po to, aby kąt pomiędzy normalną a światłem mieścił się w przedziale od 0 do 180 stopni. Wynikiem iloczynu skalarnego jak wiemy będzie liczba - cosinus kąta pomiędzy wektorami. Im większy kąt tym mniejsza wartość iloczynu i tym mniejsza liczba. Większy kąt oznacza nie mniej ni więcej to, że światło pada na daną normalną pod większym kątem, co oznacza coraz mniej światła. Nasza wartość wędruje zatem do rejestru tekstury, który zawiera współrzędne odpowiedzialne za mapowanie tekstur na poziomie nr 0 a tam znajdzie się nasza tekstura cieniująca. I jeśli tekstura będzie skonstruowana w sposób odpowiedni (dla małych wartości mapowania

3 DirectX Cell Shading będzie ciemniejsza, dla dużych jaśniejsza) to otrzymamy poprawne cieniowanie, co wiemy już z teorii. Ponieważ nasza tekstura będzie miała znaczące zmiany wartości tylko w jednym wymiarze, więc w tym momencie druga współrzędna nie ma tak naprawdę znaczenia i możemy ją ustawić dowolnie, ponieważ dla każdej wartości y, współrzędna x będzie wyglądała tak samo. ; eye vector sub r2, c8, r0 dp3 r2.w, r2, r2 rsq r2.w, r2.w mul r2, r2, r2.w Pozostało nam zatem wyliczyć już tylko dane dla tekstury wyznaczającej kontur naszego obiektu. Jak pamiętamy z lekcji teoretycznej potrzebny nam będzie wektor łączący oko z przekształconym w przestrzeni świata wierzchołkiem. Wierzchołek mamy w rejestrze r0, pozycję oka w stałej shadera c8. No i wyliczamy taki wektor odejmując pozycję wierzchołka od pozycji oka i umieszczamy w tymczasowym rejestrze r2. Oczywiście dany wektor normalizujemy, aby uniknąc przykrych niespodzianek. ; outline texture dp3 ot1.x, r1, r2 Na koniec robimy podobny manewr co poprzednio, czyli na podstawie iloczynu wektorowego będziemy wyliczać mapowanie dla tekstury. Tym razem iloczyn wyliczymy pomiędzy wektorem normalnym a wektorem, który wyliczyliśmy przed chwilą - łączącym oko z wierzchołkiem. Jeśli ten iloczyn będzie mały - znaczy się, że wektory są położone niemal prostopadle co prawdopodobnie oznacza krawędź, a przynajmniej można odnieść takie wrażenie patrząc na obiekt. Jeśli iloczyn będzie bliski zeru, znaczy że wektory leżą niemal w jednej linii i krawędź toto na pewno nie jest. Tak więc wyliczona wartość wędruje na poziom nr 1, gdzie panoszy się tekstura odpowiedzialna za pocieniowanie naszej krawędzi. Shader powinien działać bez zarzutu, czas więc zobaczyć co się dzieje w aplikacji. Jak wspomniałem, wszelkie ładowania, inicjalizacje itp. darujemy sobie, bo szkoda tylko miejsca a przejdziemy do sedna sprawy, czyli renderingu naszej bryły. W przykładzie pobawiłem się troszkę i prezentuję trzy różne możliwości renderingu: case eoutline: g_lpd3ddevice->settexturestagestate( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); g_lpd3ddevice->settexturestagestate( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_lpd3ddevice->settexturestagestate( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); Pierwszym trybem jest rendering samych krawędzi obiektu. Jak widać na rysunku krawędzie rysują się w dosyć charakterystyczny sposób i widać dodatkowo w jaki sposób jest zbudowana siatka obiektu. Taki a nie inny efekt zawdzięczać trzeba odpowiednio spreparowanej teksturze krawędzi, która zawiera zbiór odpowiednio przygotowanych mipmap. Tekstura ta jest w formacie *.dds, który jest charakterystyczny dla pakietu Direct3D. Może on zawierać nie tylko jedną teksturę, ale całe zestawy łącznie ze wszystkimi poziomami mpmap. W pakiecie Direct3D jest narzędzie, dzięki któremu możecie nawet poznać budowę takiej tekstury i obejrzeć jej posczególne elementy, no ale po szczegóły to dzisiaj odsyłam do SDK - to nie

4 DirectX Cell Shading temat na teraz. Wracając zaś do naszego przykładu to zaby zobaczyć tylko krawędzie obiektu z nałożonym na obiekt kolorem diffuse po prostu modulujemy je na poziomie nr 1, ponieważ właśnie tam znajduje się tekstura konturu. case eshade: g_lpd3ddevice->settexturestagestate( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_lpd3ddevice->settexturestagestate( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); Drugim przypadkiem renderingu dostępnym w przykładzie jest rendering wykorzystujący samo cieniowanie za pomocą tekstury cieniującej, umieszczonej na poziomie 0 bez uwzględniania konturów obiektu. Aby uwidocznić taki a nie inny sposób po prostu mieszamy na poziomie nr 0 kolor difuuse i kolor tekstury cieniującej a następnie przepuszczamy ten rezultat na poziom 1, który w naszym przypadku oczywiście zawsze jest poziomem wyjściowym. case efinal: g_lpd3ddevice->settexturestagestate( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_lpd3ddevice->settexturestagestate( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_lpd3ddevice->settexturestagestate( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); I na sam koniec oczywiście efekt w pełnej krasie czyli jednocześnie i cieiowanie i wyciąganie krawędzi. Na każdym poziomie nie robimy nic innego, tylko modulujemy kolory przychodzące z poziomów poprzednich.

5 DirectX Cell Shading No i to w zasadzie byłoby tyle, jeśli chodzi o rendering kreskówek za pomocą Direct3D. Można powiedzieć, że łatwizna i faktycznie, jeśli chodzi o kod żródłowy to raczej tak to właśnie wygląda na naszym poziomie znajomości zagadnień grafiki. Inna sprawa to odpowiednio spreparowane tekstury, które akurat w tym przypadku grają główne role. Jeśli na przykład tekstura konturu byłaby nie taka, nie zawierałaby odpowiednio spreparowanych poziomów mipmap to zapewne kontur nie byłby tak wyraźny i może trudno byłoby go wogóle dostrzec. Tekstura cieniująca natomiast jest przygotowana pod kątem cieniowania kreskówkowego - gdybyśmy na przykład zrobili z niej ładny, ciągły gradient, to otrzymalibyśmy tradycyjne cieniowanie Gourauda zamiast kilku poziomów oświetlenia i charakterystycnego efektu. Pragnę także zwrócić waszą uwagę na możliwości, jakie ze sobą niesie ta technika. Spróbójcie zresztą sami trochę poeksperymentować, zwłaszcza z teksturą cieniującą. Dodajcie do niej kanał alfa, włączcie przeźroczystość i twórzcie. Poprzestawiajcie kolory cieniujące, może dajcie zupełnie inne odcienie niż czarne. Może wpadnie wam do głowy jakiś fajny efekt z teksturą konturu na przykład? Na wszystkie ciekawe pomysły oczywiście czekamy z niecierpliwością, może jakieś dema albo najlepiej efekty do naszego browsera :). Teraz powinno być łatwiej napisać cokolwiek, więc bardzo zachęcam ;).