W podejściu warstwowym wykorzystano by serię masywnych quadów z teksturami alfa ułożonych równolegle do ziemi, przecinających całą geometrię terenu, aby zapewnić iluzję mgły naziemnej dość skutecznie z góry, patrząc w dół i nieco mniej skutecznie, gdy jest w niej mgła i patrząc w kierunku horyzontu (patrz zdjęcie poniżej).
Alternatywnie, podejście oparte głównie na module cieniującym zamiast tego obliczałoby gęstość jako funkcję odległości widoku do podłoża mgły gruntowej i na tej podstawie generowało wartość fragmentu.
Bez konieczności testowania wydajności każdego podejścia osobiście , chciałbym najpierw usłyszeć doświadczenia innych (nie spekulacje!) Na temat tego, jaki wpływ na wydajność może mieć warstwowe podejście do tekstury alfa. Pytam szczególnie ze względu na często przytaczane skutki overdraw (nie jestem pewien, jak duży jest współczynnik wypełnienia w przeciętnym systemie komputerowym). Niezwykle przydatna byłaby lista gier korzystających z tego podejścia, zwłaszcza starszych gier: jeśli byłoby to wykonalne na sprzęcie z wcześniejszych wersji DX9 / OpenGL2, prawdopodobnie działałoby dla mnie dobrze.
Jedno duże pytanie dotyczy tego rodzaju efektu:
(Kredyt na zdjęcie trafia do Lume z lume.com)
Zauważ, że pionowe gradowanie mgły jest ciągłe / płynne. OTOH, używając teksturowanych warstw quadów, mogę jedynie założyć, że warstwy byłyby niesamowicie oczywiste podczas ich przechodzenia - im były rzadsze, tym bardziej oczywiste. Jest to w przeciwieństwie do sytuacji, w których płaszczyzny mgły są ustawione tak, aby stawić czoła graczowi na każdej klatce, gdzie ta szorstkość byłaby o wiele mniej oczywista.
glFogCoord
rozszerzenie starszego OpenGL również na to pozwoliło . Choć brzmi to ograniczony: to zarówno naziemne lub oparte na odległość.Odpowiedzi:
Ponieważ poprosiłeś o doświadczenia, oto moje.
W czasach, gdy programowałem gry na PS2, podejście oparte na „warstwowych quadach alfa” było sposobem, w jaki często wprowadzaliśmy mgły. Czasami jako mgła naziemna, ale znacznie częściej jako mgła pełnoekranowa. W obu przypadkach działało dobrze. Tak, to było opłacalne w czasach shaderów sprzed fragmentów.
Cóż, w pewnym sensie. Problem, jak zauważyłeś, polegał na tym, że jeśli chcesz gładkiej mgły, takiej jak na zrzucie ekranu, potrzebujesz raczej absurdalnej liczby quadów alfa.
Na PS2 zwykle stać nas było na od trzech do pięciu warstw. Które zdecydowanie wyglądały jak „ściany” mgły unoszące się przed tobą. Co więcej, szybkość wypełniania zaczęła zabijać naszą liczbę klatek.
Zazwyczaj te quady byłyby rysowane w ustalonych odległościach przed kamerą, więc nigdy nie dostałeś sytuacji, o której wspominałeś, „przechodząc” przez jedną z nich. Z drugiej strony, stosując te ustalone odległości, robi wszystko inne na świecieprzechodzą przez te samoloty, gdy gracz się porusza, co jest dość oczywistą usterką graficzną. Prawie wszyscy robili to wtedy, ale teraz nie byłoby to do przyjęcia (chyba że robiłeś to ze względów stylistycznych). (Wyjątek: niektórzy ludzie obliczali wartości mgły jako część ekwiwalentu cieniowania wierzchołków na PS2. To działało i było znacznie szybsze, ale wymagało silnego mozaikowania modeli. Na przykład nie można było mieć długich ścian, ponieważ mgła była tylko obliczany w rogach ściany, a następnie rozsmarowywany po całej powierzchni ściany. Ściana wyglądała na całkowicie zamgloną, jeśli na przykład stałeś tuż obok jej środka, ponieważ testował tylko poziomy mgły na jej powierzchni punkty końcowe)
Pamiętaj, że jeśli umieścisz quady mgły statycznie na świecie (jak wspominasz jako możliwość), to nie będziesz w stanie uzyskać wyjątkowo gładkiej mgły, jak na obrazie, który podajesz - dziwne nakładanie się sąsiednie kwadraty w zależności od orientacji widza. Te zakładki mogą pojawiać się jako paski lub trapezoidy (jeśli quady nie są teksturowane) lub jako grudki (jeśli są teksturowane).
Załóżmy jednak, że do wykonywania tej mgły naziemnej używamy szerokich quadów i wykonujemy obliczenia, jak zrobić naprawdę gładką mgłę za pomocą tej metody, na płaskim terenie, z kamerą skierowaną prosto do przodu - to nasza idealna sytuacja . Załóżmy rozdzielczość HD: 1920x1080, która ustawia nasz horyzont na linii skanowania 540. Załóżmy również, że mamy widoczność aż do horyzontu (to znaczy zakładając, że mgła nie osiąga pełnego krycia przed dotarciem do horyzontu). Z jednym początkiem kwadratu mgły i jednym zatrzymaniem na każdej linii skanowania (w celu uzyskania gładkiej mgły) potrzebujemy (540 * 2 ==) 1080 quadów mgły. Każdy z 1080 quadów mgły obejmie całą poziomą przestrzeń ekranu,
Oszacujmy nisko i powiedzmy, że średnio mgła pokryje około 300 rzędów pikseli. Najbliższe pokryją mniej, najdalsze pokryją mniej, środkowe rzędy zajmą znacznie więcej.
Przy takim oszacowaniu otrzymujemy (1920 x 300 ==) 576 000 pikseli dotkniętych przez średni quad mgły. W sumie jest to (576,000 * 1080 ==) 622,080 000 pikseli dotkniętych łącznie dla całej „gładkiej mgły poprzez renderowanie dużej ilości półprzezroczystej geometrii”. Liczba ta wzrośnie dla osób pracujących w wyższej rozdzielczości. Co więcej, otrzymujemy taką samą liczbę testów z buforem Z i prawie taką samą liczbę operacji mieszania pikseli, ponieważ wszystkie te przezroczyste warstwy rysują się nawzajem raz po raz. To dużo pikseli.
I to jest najlepszy scenariusz - jeśli użytkownik patrzy w dół lub kuca, uzyskasz znacznie większy zasięg quadów.
Zauważ, że ponieważ nakładamy się na siebie 1080 quadów, prawdopodobnie chcemy ustawić wartość alfa wynoszącą około (1,0 / 1080 ~ =) 0,0009 na każdym z nich, aby nasza mgła osiągnęła pełne krycie, jeśli spojrzysz na wszystkie quady 1080. (Moglibyśmy pójść wyżej, ale jest to wartość zakładając, że chcemy rozszerzyć zakres w jak największym stopniu). Zauważ, że tej wartości nie można przedstawić jako składnika alfa 32-bitowej wartości koloru (256 * 0,0009 ~ = 0,237, więc zostanie zaokrąglona w dół do 0, jeśli spróbujesz). Musisz podać wartość 0.0009 dla OpenGL jako wartość zmiennoprzecinkową, aby to w ogóle zadziałało. (Zauważ też, że tak naprawdę nie będziesz chciał ustawiać tej samej wartości dla każdego z nich - podczas gdy ustaliliśmy, że chcemy, aby jeden poczwórek zaczął i jeden na każdej linii skanowania poniżej horyzontu, aby zapewnić nam płynną mgłę,
Zauważ też, że mieszanie mgły nie działa całkiem poprawnie przy takim podejściu, podobnie jak w przypadku nowoczesnego modułu cieniującego - zamiast jednego obliczenia „mieszania podstawowego koloru obiektu z kolorem mgły przy użyciu tego procentu”, otrzymujesz 1080 obliczenia „mieszania dotychczasowego koloru z kolorem mgły według procentu mgły”. Co oznacza, że mgła wpłynie na obiekty po logarytmicznym spadku. (Oznacza to, że obiekt dotknięty 20 czworokątami mgły pojawi się mniej niż dwa razy tak mgliście, jak coś dotkniętego 10 czworokątami mgły, ponieważ pierwsze kwadraty mgły mają większy wpływ na operację mieszania).
Wszystko to znaczy: użyj po prostu shadera fragmentów.
Nie naprawdę. Jest prostszy i tańszy oraz szybszy i szybszy we wdrożeniu oraz mniej podatny na błędy i pozwala wrócić do tworzenia gry i jest lepszy pod każdym możliwym względem. Zrobilibyśmy to całkowicie w erze PS2, gdyby było to w tym czasie nawet niejasno możliwe.
źródło