Pracuję nad ustawieniem aktywnego konturu w moim silniku 3d, efektu podświetlenia dla wybranych postaci 3d lub scenerii na ekranie. Po pracy z buforem wzornika i uzyskaniu niezadowalających wyników (problemy z wklęsłymi kształtami, grubość konturu z powodu odległości od kamery oraz niespójności między moim komputerem stacjonarnym a laptopem), przełączyłem się na wykrywanie krawędzi i próbkowanie bufora ramki i otrzymałem zarys: bardzo zadowolony z.
Nie jestem jednak w stanie ukryć konturu, gdy wybrana siatka znajduje się za inną siatką. Ma to sens biorąc pod uwagę mój proces, ponieważ po renderowaniu reszty sceny renderuję po prostu kontur 2D modułu cieniującego z bufora ramki.
Poniżej dwa zrzuty ekranu z moich wyników. Pierwszy to „dobry” kontur, drugi to miejsce, w którym kontur jest widoczny nad siatką, która blokuje źródło konturu.
Proces renderowania przebiega w następujący sposób: 1) Narysuj tylko alfa podświetlonej siatki, przechwytując czarną sylwetkę w buforze ramek (framebuffer1).
2) Przekaż teksturę z bufora ramki 1 do drugiego modułu cieniującego, który wykonuje wykrywanie krawędzi. Uchwyć krawędź w buforze ramki 2.
3) Renderuj całą scenę.
4) Renderuj teksturę z framebuffer2 na górze sceny.
Mam kilka pomysłów, jak to osiągnąć i mam nadzieję uzyskać informacje zwrotne na temat ich ważności lub na temat prostszych lub lepszych metod.
Po pierwsze, pomyślałem o renderowaniu całej sceny do bufora ramki i zapisaniu widocznej sylwetki podświetlonej siatki w kanale alfa (cała biała próba, gdzie widoczna jest podświetlona siatka). Następnie wykonałbym wykrywanie krawędzi na kanale alfa, renderowałem bufor ramki sceny, a następnie renderowałem krawędź na górze. W wyniku czego coś takiego:
Aby to osiągnąć, pomyślałem o ustawieniu definicji tylko podczas przejścia renderowania podświetlonego obiektu, który rysowałby całą czerń w alfie dla wszystkich widocznych pikseli.
Moim drugim pomysłem jest użycie bieżącego procesu renderowania opisanego powyżej, ale także zapisanie współrzędnych X, Y i Z w kanałach R, G i B bufora ramki 1 podczas renderowania sylwetki wybranej siatki. Wykrywanie krawędzi będzie wykonywane i przechowywane w framebuffer2, ale przekażę wartości RGB / XYZ od krawędzi alfa do sylwetki. Następnie podczas renderowania sceny sprawdziłbym, czy współrzędna znajduje się w krawędzi przechowywanej w framebuffer2. Jeśli tak, przetestowałbym głębokość bieżącego fragmentu, aby ustalić, czy znajduje się on przed czy za współrzędnymi wydobytymi z kanałów RGB (przekonwertowanych na przestrzeń kamery). Jeśli fragment znajduje się przed współrzędnymi głębokości, fragment byłby renderowany normalnie. Jeśli fragment znajduje się w tyle, byłby renderowany jako jednolity kolor konturu.
Używam LibGDX do tego projektu i chciałbym wspierać WebGL i OpenGL ES, więc żadne z rozwiązań obejmujących shadery geometrii lub nowsze funkcje GLSL nie jest dla mnie dostępne. Gdyby ktoś mógł skomentować moje zaproponowane podejście lub zaproponować coś lepszego, naprawdę bym to docenił.
Odpowiedzi:
Przekształciłbym całą scenę w bufor wzornika z pożądanym obrysowanym obiektem, aby ustawić bit i wszystko inne, aby odrzucić / usunąć bit.
Następnie pozbądź się wykrywania krawędzi, nie potrzebujesz tego, zamiast tego możesz po prostu trochę przeskalować bufor. Tak więc każdy przedmiot nieznacznie rośnie.
Stamtąd bufor szablonów może mieć potrzebny kontur. Chodzi o to, aby upewnić się, że inne obiekty, które renderujesz, wyłączają bity w buforze szablonów.
źródło
1) w obiekcie bufora ramek można uruchomić moduł cieniujący laplacian w GPU, aby uzyskać kontur.
2) musisz użyć końcowego bufora głębokości podczas rysowania obiektu w FBO, w ten sposób narysujesz tylko widoczną część obiektu w FBO, a laplacian obrysuje tylko widoczną część.
źródło
Mam nadzieję, że mogę to wyjaśnić, ale w zasadzie musisz zrobić szablon obu obiektów tak, jakby były one wybrane, a następnie zachować tylko pola w obwiedni elementu, który faktycznie chcesz podświetlić.
Zasadniczo tworzysz jeden bufor szablonów dla obu wybranych obiektów (lub wszystkich obiektów, które zasłaniają obiekt, naprawdę ... ale nie martwiłbym się tymi przypadkami, chyba że tak naprawdę pojawia się dużo - jeśli to okludowane ludzie nie będą się spodziewać ta pomoc), a następnie szablonem obwiedni dla Twojego obiektu.
To powinno dać efekt, którego szukasz.
Alternatywnie możesz po prostu zostawić „zły” wynik i nie sądzę, że większość ludzi będzie się tym przejmować, choć zależy to od twoich danych / gry, a zwłaszcza wielkości obiektów.
źródło