Chciałbym wiedzieć, jak zrobić ten efekt wyboru scalonego okręgu. Oto zdjęcia do zilustrowania:
Zasadniczo szukam tego efektu:
Jak można uzyskać efekt scalenia kręgów? Nie znalazłem żadnego wyjaśnienia tego efektu. Wiem, że aby wyświetlić te tekstury, mogę opracować system kalkomanii, ale nie wiem, jak stworzyć efekt łączenia.
Jeśli to możliwe, szukam rozwiązania czysto shaderów.
Odpowiedzi:
Istnieje kilka sztuczek, które możesz zrobić:
Bufor Z.
Po renderowaniu wszystkich innych obiektów, dla każdej jednostki renderuj przezroczysty okrąg o mniejszym rozmiarze z maksymalną wartością Z. Następnie renderuj na ziemi naklejki z okręgami wyboru. Ponieważ znajdują się poniżej w kolejności Z, zostaną odrzucone, gdy znajdują się poniżej jednostek.
Bycie w pełni przezroczystym oznacza, że okrąg jest zapisywany tylko do bufora Z (maksymalna wartość Z). Teraz, gdy renderujesz kalkomanie, są one testowane pod kątem wartości bufora Z, a jeśli pomyślnie przejdą test, są renderowane (co dzieje się tylko poza kręgami)
Szablon
Tak samo jak w poprzednim podejściu, ale tym razem użyj bufora szablonów. Renderuj mniejsze koła dla jednostek z pewną wartością szablonu, a następnie renderuj naklejki wyboru. Skonfiguruj szablon, aby odrzucić wszystkie elementy o wartości szablonu.
źródło
Możesz na przykład sprawdzić w module cieniującym piksele renderujące, czy istnieje przecięcie z innymi naklejkami i zabić piksel, jeśli tak jest. Jest to dość skuteczne w przypadku tego rodzaju okrągłych naklejek.
źródło
Masz na myśli te niebieskie kółka na ziemi?
Może to być mądrzejszy sposób, aby to zrobić, ale rozważ moje rozwiązanie jako przykład, jak można to zrobić. Renderuj kręgi do osobnej pustej tekstury wielkości ekranu. W tym momencie możesz je ze sobą łączyć, jak chcesz. W zależności od potrzeb możesz napisać pełny kolor lub po prostu informację, że koło ma dany piksel. Jednak zdecydowanie potrzebujesz informacji o głębokości dla każdego zapisanego piksela, jeśli chcesz uzyskać efekt testu Z.
Podczas renderowania terenu po poprzednim kroku możesz próbkować utworzoną wcześniej teksturę, używając współrzędnych ekranu w module cieniującym piksele, jako UV. Teraz już wiesz, że okrąg powinien lub nie powinien być rzutowany na dany piksel terenu. Jednak w ten sposób będzie działać, jakby test Z był wyłączony, więc teren nie może ukryć żadnego koła. Jeśli chcesz, aby teren ukrywał koła znajdujące się za nim, wykonaj test głębokości przed zmieszaniem koła z teksturą terenu. Możesz użyć małego odchylenia, aby umożliwić renderowanie okręgów, które są nieco pod powierzchnią terenu, ale nadal chcesz je renderować.
Edycja: Teraz, aby uzyskać efekt scalonych kręgów, musisz: Podczas renderowania do osobnej tekstury musisz sprawdzić, czy istnieje już renderowany okrąg, w którym próbujesz wyrenderować nowy. (Sprawdź, czy tekstura ma tam wartość), jeśli tak, usuń ten piksel. Powinno to dać efekt „konturu”, gdy dwa lub więcej kół nakładają się na siebie. Aby działało to poprawnie, należy wykonać ten test tylko dla wnętrza koła, a nie granicy. Podczas renderowania okręgów zapisz określoną wartość do tekstury wyjściowej, która wskazuje, że jest to koło wewnątrz. Więc po prostu nie musisz renderować niczego na okręgu wewnątrz i powinieneś być dobry.
Edycja2: Dla Twojego prostego przykładu czerwony / zielony: Przed renderowaniem dowolnego piksela sprawdź, czy ten piksel nie jest już zielony. Jeśli tak, nie renderuj. To załatwi sprawę. W rzeczywistości, pisząc do tekstury, możesz nawet użyć czerwonego / zielonego na zewnątrz / wewnątrz koła, a następnie podczas renderowania terenu odczytaj te wartości i przekonwertuj je na pożądany kolor.
Jeśli przypadkiem moja odpowiedź jest zbyt abstrakcyjna, daj mi znać.
źródło
Istnieje kilka opcji. Jako ogólna metoda, bufory szablonów często przydają się w miejscach, w których konieczne jest maskowanie niektórych rysunków, takich jak kontur, w którym koła pokrywają się w twoim przykładzie.
W tym przypadku myślę, że można to zrobić równie łatwo bez bufora szablonów. Możesz użyć bufora głębokości, aby wyeliminować kontur, w którym koła się nakładają. Chodzi o to, że narysujesz wnętrze kręgów tylko w buforze głębokości (ponieważ nie chcemy widzieć wnętrza), a następnie narysujesz kontur. W ten sposób część konturu pokrywająca się z innym okręgiem zostanie wyeliminowana przez test głębokości.
Jedynym zastrzeżeniem jest to, że musisz uważać na głębokość walki. Możesz użyć małego przesunięcia, aby upewnić się, że kontury faktycznie znajdują się za wnętrzem i zostać wyeliminowanym przez test głębokości. Alternatywą byłoby użycie
glPolygonOffset()
.Powiedzmy, że masz dwa okręgi, które są równoległe do płaszczyzny xy, ze środkami w (x1, y1, z) i (x2, y2, z). I masz te funkcje rysowania:
Sekwencja rysowania wygląda wtedy tak, z
delta
niewielkim przesunięciem:źródło
Jeśli te kalkomanie są narysowane jako dyski, z czubka mojej głowy przetestowałbym każde koło pod kątem przecięcia ze sobą i umieściłem punkty przecięcia w tablicy. Następnie narysuj łuki, które nie znajdują się w przecięciu. Nie jest to jednak rozwiązanie cieniujące.
źródło
Chcesz się wzorować tutaj. Twoje pierwsze przejście renderuje koła w buforze szablonu. Drugi przebieg renderuje widoczny kontur , wszędzie tam, gdzie bufor szablonów się nie zmienił. Drugie przejście musi wykorzystywać geometrię większą niż pierwsze przejście, w tym przypadku wystarczy prosty skalar liniowy.
Chociaż rozwiązanie, które mam tutaj do rysowania konturów , jest więcej niż potrzebujesz (ponieważ ten moduł cieniujący zamienia każdą krawędź siatki w pełny quad), stosuje się to podejście: rysowanie oryginalnego modelu w buforze szablonów, a następnie renderowanie większej wersji, w której bufor szablonu nadal wynosi 0.
źródło