22 sierpnia 2006

Ostatnio troche czasu spedzilem nad tworzeniem oswietlenia do mojego silnika i chcialbym dzisiaj zaprezentowac moje przemyslenia na ten temat.

Zalozenia jakie sobie postawilem byly dosc proste: swiatla punktowe w dowolnym kolorze, oswietlajace tylko te obiekty ktore sa pod nimi i pozostawiajace nie oswietlone te obiekty ktore sa "wyzsze od swiatla", do tego wszystkiego chcialem zrobic cienie. "Wyzsze od swiatel" jest umowne bo moj silnik jest przeznaczony dla gier 2d z widokiem z gory, wiec tak naprawde nie ma sposobu na okreslenie wysokosci obiektow.

Pierwszym problem jaki napotkalem bylo jak zrobic zeby obszar gdzie nie ma swiatla byl zaciemniony? Zrobilem to tak ze najpierw renderuje wszystkie obiekty normalnie, pozniej renderuje swiatla do textury. Robie to w ten sposob ze podmieniam tylko backbuffer natomiast zbuffer pozostawiam bez zmian. Przed renderowaniem swiatel czyszcze caly ekran na jakis okreslony kolor ktory przyjmuje za brak oswietlenia.
Pozostawiajac Z buffor wypelniony wartosciami Z obiektow mam pewnosci ze beda oswietlone tylko te obiekty ktore sa pod swiatlem, a obiekty nad swiatlem pozostana nie oswietlone.
Oto stany mieszania jakich uzywam (DirectX 9):

engine->setRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
engine->setRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

Uzylem, D3DBLEND_ONE poniewaz w rzeczywistosci miejsca oswietlane przez dwa swiatla sa bardziej oswietlone niz te oswietlone tylko jednym swiatlem.

Po wyrenderowaniu wszystkich swiatel, wyswietlam texture do ktorej renderowalem na calym ekranie. Z takim mieszaniem kolorow:

engine->setRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); engine->setRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);

Dzieki temu powstaje odpowiedni efekt oswietlenia.

Kolejnym punktem jaki chcialem zrealizowac to rzucanie cieni. W obecnej wersji cienie nie sa rzucane przez mesh, a przez obiekt Collidera (z tego wzgledu ze jako jedyny ma wyroznione krawedzie).

Na tym screenie widac poprawnie wyswietlony cien:














Obiekt z duza czerwona kropka jest wyzszy od pozostalych i jak widac poprawnie rzuca na nie cien. Pozostale obiekty sa na tej samej wysokosci i nie rzucaja na siebie cieni.

Rzucanie cieni odbywa sie w ten sposob, ze bierzemy obiekt i swiatlo. Znajdujemy wszystkie krawedzie dla ktorych iloczyn skalarny wektora z pozycji swiatla do srodka krawedzi i normalnej dla tej krawedzi jest > 0. Na podstawie tych krawedzi dodajemy dodatkowe trojkaty przedstawiajace rzucany cien. Dlugosc cienia jest wprost proporcjonalna do odleglosci od zrodla swiatla. W kilku artykulach na sieci widzialem, ze wystepuje problem gdy zrodlo swiatla zawiera sie w obiekcie. U mnie jest to tak rozwiazane wlasnie przez okreslanie dlugosci cienia oraz zalozenia ze swiatlo jest zawsze nad obiektem (nawet jesli teoretycznie leza na tej samej plaszczyznie).

Kolejnym problemem jaki trzeba rozwiazac przy rzucaniu cieni jest obszar pozbawiony swiatla bardzo rzadko jest w stu procentach czarny (moze byc np. poranek lub wieczor) wiec jesli obiekt bedzie na granicy zasiegu swiatla bedzie rzucal cien ale sam cien bedzie juz poza zasiegiem i bedzie tworzyl dziwny efekt przyciemniania obszaru gdzie nie ma swiatla. Moim rozwiazaniem jest wprowadzenie przezroczystosci cienia w zaleznosci od odleglosci od zrodla swiatla. Jesli cien jest na granicy dzialania swiatla to jest calkowicie przezroczysty. Oprocz tego wprowadzilem brak przezroczystosci cienia najblizej obiektu i prawie calkowita przezroczystosc w obszarze najbardziej oddalonym od obiektu.

Ostatecznie otrzymalem taki dosc ladny jak mi sie wydaje efekt:











Na srodku widac co sie dzieje gdy swiatlo jest idealnie nad obiektem.

To na tyle dzisiaj. Pozdrawiam i zapraszam za jakiś czas. Teraz zajmuje sie texturowaniem terenu.

Komentarze:
myslales o softshadowsach?
 
myślalem, nawet zrobilem! tylko tyle, ze efekt nie wygladal jakos super ladnie... glownie dlatego ze mam rozjasnianie cieni w zaleznosci nie tylko od odleglosci od swiatla ale tez od odleglosci od obiektu i zmiekczanie cieni dawalo slaby efekt. Ogolnie uznalem ze wiecej z tym problemow niz korzysci :)
 
a myslales zeby wszystko zgrac z bumpmappingiem? ja wlozylem to do dalszych planow :)
 
mam w planach zeby dodac bumpmapping do silnika ale prawde mowiac nie mam pojecia jeszcze jak to zrobie :) wiec wole nic narazie nie mowic (pewna osoba mi w takich mometach mowi ze powinienem zrobic risercz :)) Mialem robic edytor terenu teraz ale mam problem z wxwidgets wiec zostawiam to narazie, na jutro zaplanowalem reorganizacje silnika (juz ktoras z kolei) i potem bede pisal particle, potem moze bumpa - chcialem tez glow zrobic :) Jesli cos zrobie w tym kierunku to napewno tutaj zobaczysz
 
Prześlij komentarz

Subskrybuj Komentarze do posta [Atom]





<< Strona główna

This page is powered by Blogger. Isn't yours?

Subskrybuj Posty [Atom]