Rzucanie cieni w czasie rzeczywistym w izometrycznej grze 2D

15

Piszę mały izometryczny silnik 2d w C ++ i próbuję zaimplementować rzucanie cieni w czasie rzeczywistym. Postępowałem zgodnie z prostym podejściem opisanym na tej stronie i oto wynik (światło znajduje się w tym samym miejscu co żółty sześcian):

wprowadź opis zdjęcia tutaj

Rezultat jest bardzo ładny, ale na ścianach i na kostkach brakuje cieni. Oto przykład, jak powinien on wyglądać (narysowałem oczekiwane cienie na zielono):

wprowadź opis zdjęcia tutaj

Wszystkie narysowane kostki są po prostu wykonane z 3 kwadratów 2D umieszczonych w pozycji XY i o głębokości Z (z = x + y). Używam OpenGL z matrycą ortograficzną (glOrtho). Cienie są rysowane za pomocą bufora szablonów.

Szukam zasobów lub rozwiązań, które pomogłyby mi ukończyć tę implementację rzutowania w tle.

Wielkie dzięki!

XPac27
źródło
5
Twój link do „tej strony” wskazuje obraz, a nie stronę. Zgaduję też tutaj, ale może być łatwiej rozwiązać ten problem w 3D i po prostu rzutować kamerę kosmetycznie.
Tetrad
Ups, masz rację, naprawiłem link. Z pewnością byłoby łatwiej z projekcją 3D, ale 2D ma również swoje zalety i jestem pewien, że istnieją rozwiązania, które mogłyby to zaimplementować w 2D.
XPac27

Odpowiedzi:

6

W przypadku dachu i ścian możesz spróbować określić przecięcia między segmentami ściany i wygenerowanymi obszarami cieni. Potrzebujesz dwuprzebiegowego renderowania cieni. Pierwszy zrobi to, co robisz dzisiaj (w pamięci). Drugie przejście obliczy przecięcia dachu i ściany. Ostatni etap to prawdziwy rendering. DeadMG się myli, możesz to zrobić.

Uwaga: w przypadku dachu należy przeciąć obszar cienia i obszar dachu.

sgc
źródło
Dziękuję za dobrą radę! Jeśli może być w stanie zoptymalizować to drugie przejście, sprawdzając, które ściany należy obliczyć, stosując iloczyn iloczynu ich segmentu w porównaniu do ścian segmentów cienia. Spróbuję tego i odeślemy, jeśli to zadziała.
XPac27
Minęło trochę czasu, ale w końcu udało mi się działać dzięki twoim sugestiom! Potrzebowałem tylko 2 metod geometrii (jednej, aby wiedzieć, czy punkt znajduje się w wielokącie, a drugiej, aby uzyskać przecięcie dwóch segmentów). Nadal muszę obsługiwać dachy, ale wygląda na to, że łatwo to wiedzieć. Możesz obejrzeć wynik na tym filmie i spojrzeć na kod źródłowy tutaj (właśnie pracowałem nad nim 1 dzień, więc może być możliwe zoptymalizowanie go bardziej).
XPac27,
@ XPac27, który jest niesamowity. Dzięki za udostępnienie.
ashes999
0

Zasadniczo nie można zrobić tego, czego szukasz. Chcesz wziąć kilka obiektów 2D i sprawić, by rzucały cienie, jakby były obiektami 3D. Jeśli chcesz mieć pełne cienie 3D, musisz mieć obiekty 3D.

DeadMG
źródło
1
Ale to nie jest rzucanie cienia w 3D, jak w pytaniu. Każda ściana całkowicie blokuje linię wzroku w tym kierunku, nie możesz mieć obiektów o zmiennej wysokości.
yuriks
0

Opisane rozwiązanie nie jest pełne 3D, ponieważ nie potrzebuje pełnego rozwiązania 3D. Będzie to wyglądać, ale tak nie jest. Tworzenie rzucania cieni należy traktować jako przecięcie objętości. To, czego potrzebuje, jest mniej skomplikowane. Pamiętaj (jeśli posiadasz znanego) zagłady i zagłady, takie jak silnik renderowania. Wszystkie przetwarzanie przeprowadzono w dwóch wymiarach.

sgc
źródło
0

Biorąc pod uwagę, że chcesz, aby ta gra była mała, co powiesz na to, że obecna implementacja cienia jest wystarczająco dobra?

Przyznaję, że nie widziałem tego w akcji, to znaczy nie widziałem, jak niepokojące lub niezakłócające będą niedoskonałości cienia, gdy gry będą działać na żywo z dynamicznymi obiektami i dynamicznymi źródłami światła, ale sądząc po twoich obrazach, „ bardzo chciałbym powiedzieć „jest wystarczająco dobry, teraz skup się na ukończeniu gry”. Jeśli obecna implementacja będzie mała i zostanie wykonana szybko, a naprawienie tego, co uważasz za problemy, spowoduje, że kod będzie duży i powolny, myślę, że lepiej nie martwić się o te cienie.

Wiem, wiem, sugerowanie „nie próbuj rozwiązać problemu”, ponieważ rozwiązanie problemu może być złą praktyką. Mimo to szczerze chcę powiedzieć, że jest naprawdę dobry, jeśli chcesz mieć niewielki ślad w kodzie.

IllvilJa
źródło