Czy mogę uzyskać efekt pochodni (jaśniejszy obszar wokół źródła światła) w grze 2D?

16

Zastanawiam się nad napisaniem prostej gry 2D. Na początku nie zabłyśnie w doskonałej grafice lub rozgrywce, ale uważam to za pierwszy krok w rozwoju gier komputerowych. Wyobraź sobie więc taką prostą grę 2D opartą na ikonkach (jak Heroes IV lub Startcraft BroodWar).

Chcę, aby rozgrywka wspierała dzień / noc przy odpowiednich zmianach oświetlenia, a jednocześnie szaleństwem będzie tworzenie duszek dla każdego niuansu oświetlenia. Zdecydowałem więc, że dodanie półprzezroczystej warstwy na wierzchu innych obiektów będzie wystarczające.

Problem z tym rozwiązaniem polega na tym, że jeśli w grze mam obiekt będący źródłem światła (np. Bohater noszący pochodnię lub płonący budynek), wokół niego musi znajdować się jaśniejszy obszar, prawda? Skoro nakładam na siebie moją półprzezroczystą warstwę, jak sugerowałbyś osiągnięcie pożądanego efektu wizualnego pochodni? Może przerysuj tę warstwę, dodając „luki” lub obszary o różnych kolorach w zależności od efektu oświetlenia?

Ivaylo Slavov
źródło
2
Maska może być dobrą drogą
Gustavo Maciel
5
„Torchlight” w tytule może być mylące ze względu na grę o nazwie Torchlight.
Tetrad
4
@Tetrad Powinno być w porządku, o ile nie jest pisane wielkimi literami. Co do mnie, Torchlight nie przyszło mi do głowy aż do przeczytania twojego komentarza.
famousgarkin
Niemniej jednak zasugerowałem edycję, aby uściślić tytuł.
famousgarkin
2
możliwy duplikat Jak realizowane jest oświetlenie 2D?
bummzack

Odpowiedzi:

12

Nie wiem, w czym programujesz, ale tak sobie z tym poradziłem w XNA:

  1. Podczas wywołania losowania List<Light>obiekt jest tworzony / usuwany.
  2. Podczas pętli losowania kafelków każdy kafelek jest sprawdzany, aby sprawdzić, czy ma z nim jakieś Światła. Jeśli tak, Lightobiekty są dołączane do List<Light>.
  3. Kafelki są rysowane same RenderTarget2D.
  4. Po pętli kafelkowej lista Lights jest iterowana i rysowana samodzielnie RenderTarget2Dprzy użyciu utworzonej przeze mnie tekstury, która wygląda tak:
    Lekka konsystencja(Uwaga: Użyłem tutaj wartości R, G i B, ale prawdopodobnie powinieneś użyć kanału alfa w swoim faktyczna tekstura.)
  5. Używając niestandardowego modułu cieniującego, renderuję powierzchnię kafelka na ekran i przekazuję powierzchnię oświetlenia jako parametr, który jest próbkowany pod kątem wartości „ciemności” przy każdym pikselu.


Warto zwrócić uwagę na kilka rzeczy:

W odniesieniu do punktu 4:

Mam dwa niestandardowe moduły cieniujące, jeden do narysowania świateł do celu renderowania oświetlenia (krok 4), a drugi do narysowania celu renderowania kafelków na ekranie za pomocą celu renderowania oświetlenia (krok 5).
Moduł cieniujący użyty w punkcie 4 pozwala mi dodać (jak to nazywam) wartość „luminosity”. Ta wartość jest floatmnożona przez każdy piksel w teksturze, zanim zostanie dodany do celu renderowania, dzięki czemu mogę zasadniczo rozjaśnić lub przyciemnić światła.
W tym momencie biorę również pod uwagę wartość „skali” światła, co oznacza, że ​​mogę mieć duże lub małe światła przy użyciu tylko jednej tekstury.

W odniesieniu do punktu 5:

Pomyśl o celu renderowania oświetlenia, który zasadniczo ma wartość dla każdego piksela od 0 (czarny) do 1 (biały). Moduł cieniujący zasadniczo zwielokrotnia tę wartość w stosunku do wartości RGB piksela w celu renderowania kafelków, aby utworzyć ostatecznie narysowany obraz.

Mam też trochę kodu, w którym przekazuję (do modułu cieniującego) wartość, która ma być użyta jako kolor nakładki dzień / noc. Jest to również mnożone przez wartości RGB i uwzględniane w obliczeniach celu renderowania oświetlenia.


Teraz nie pozwoli ci to robić takich rzeczy jak blokowanie światła przed obiektami i tak dalej, ale przynajmniej dla moich celów jest to proste i działa dobrze.

Pisałem bardziej szczegółowy blogu tutaj i tutaj , które mogą Ci pomóc. Nie mam teraz czasu, ale jeśli chcesz, mogę zagłębić się tutaj w gamedev.

Aha, a oto spojrzenie na to w moim edytorze map:wprowadź opis zdjęcia tutaj

Richard Marskell - Drackir
źródło
Wygeneruj i wyczyść listę każda ramka może nie być zbyt kosztowna?
Gustavo Maciel
@Gtoknu Nie robi zauważalnej różnicy w mojej grze. Lista zawiera tylko odniesienia do obiektów, które już istnieją w pamięci, więc nie jest tak, że każde światło jest odtwarzane, czy cokolwiek innego, tylko jedna lista.
Richard Marskell - Drackir
możesz mieć rację, nie do końca, ale jesteś. Oczywiście, nie tworzysz pełnych obiektów, ale dodajesz wskaźniki do referencji, wciąż mało użytkowane, ale wciąż konsumujące. Robisz dobrze, ale myślę, że może być lepiej, jeśli umieścisz listę poza metodą losowania, ponieważ logika w aktualizacji jest znacznie szybsza niż w losowaniu
Gustavo Maciel
@Gtoknu Pewnie, możesz zadeklarować listę gdziekolwiek chcesz, ale chodzi o to, że światła są powiązane z kafelkami. Metoda kafelkowa Drawpolega na sprawdzeniu, czy kafelek ma światła, czy nie. W Updatemetodzie nie przeglądam wszystkich narysowanych płytek , więc dodałbym za to dodatkowe koszty. Ponadto XNA stara się zagwarantować, że Updatebędzie wywoływany 60 razy na sekundę, więc może poświęcić Drawwywołania z tego powodu, co oznacza, że ​​ten kod będzie wywoływany rzadziej.
Richard Marskell - Drackir
To powiedziawszy, jest to kwestia sporna, ponieważ ostatecznie przeniosłem światła na ich własne listy oparte na podziale przestrzennym i po prostu narysowałem wszystkie światła w sekcjach przecinających ekran. Nie mówiłem o tym w moim poście z braku czasu, ale jest to wspomniane w drugim poście na blogu, który podlinkowałem.
Richard Marskell - Drackir
9

Zwykle oświetlenie w grach 2D odbywa się poprzez utworzenie mapy normalnej dla wszystkich duszków, a następnie obliczenie efektów świetlnych 3D na duszkach 2D. Nazywa się to luźno „2.5D”. Nie poleciłbym jednak tego robić w pierwszej grze, ponieważ jest to skomplikowane.

Oto niesamowite wideo osoby, która zrobiła to w XNA: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

To powiedziawszy, są prawdopodobnie sposoby oszukiwania i uzyskania pseudo-oświetlenia, który mógłby działać przy różnych założeniach.

John McDonald
źródło
Już widziałem ten film wcześniej, +1 za wzmiankę o tak niesamowitej technice.
Gustavo Maciel
Dziękujemy za radę i link do filmu. Rzeczywiście mapa wydaje się rozwiązaniem. Sam spróbuję użyć mapy na mojej górnej warstwie, aby stworzyć „lukę” lub zmienić efekt, jaki wywiera ona na leżące pod nią obiekty.
Ivaylo Slavov,
5

Trudno zasugerować takie podejście, jeśli nie jesteś całkowicie konkretny co do efektu, który próbujesz osiągnąć. Szczegóły, takie jak to, czy światło powinno być zasłonięte przez środowisko, czy nie, jaki jest punkt twojej gry, w jakim stopniu światło powinno oddziaływać z otoczeniem itp.

Wpuszczę jednak dwa centy. Sprawdź, czy ten samouczek Catalin Zima zatytułowany Dynamiczne cienie 2D pasuje do Twojego rachunku. Jak widać, światło ma promień i nie przechodzi przez przeszkody. Możesz trochę ożywić promień i kolor, aby zbliżyć się do prawdziwego światła pochodni.

wprowadź opis zdjęcia tutaj

W tym przypadku światło działa jak rodzaj nakładki na twoją scenę, ale nie wchodzi w interakcje z nim w takim samym stopniu jak w przykładzie Johna, chociaż bierze pod uwagę przeszkody.

Edytować

Catalin prowadzi do innego artykułu, który wykorzystał jako odniesienie, ale link jest zepsuty. Oto zaktualizowany link .

David Gouveia
źródło
Dzięki, myślę, że nie jest to efekt, którego szukam, ale wciąż dziękuję za udostępnienie :)
Ivaylo Slavov