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ł.