Mam świat oparty na kostkach, taki jak Minecraft i zastanawiam się, czy istnieje sposób na zbudowanie kostki z mniej niż 24 wierzchołkami, aby zmniejszyć zużycie pamięci.
Wydaje mi się to niemożliwe z dwóch powodów: normalne nie wyszłyby dobrze, a tekstury na twarz nie działałyby.
Czy tak jest, czy się mylę? Może jest jakaś nowa, wymyślna technologia DX11, która może pomóc?
Edycja: Żeby wyjaśnić, mam 2 wymagania: potrzebuję normałów powierzchni dla każdej powierzchni kostki, aby wykonać odpowiednie oświetlenie i potrzebuję sposobu na zajęcie się innym indeksem w tablicy tekstur dla każdej powierzchni kostki
Odpowiedzi:
Jeśli potrzebujesz tylko normalnych na twarz, a jeśli twoje texcoords dla twarzy są ściśle 0/0, 0/1, 1/0, 1/1 (lub podobne do twojego układu), możesz zbudować sześcian z 8 wierzchołkami oraz indeksy 30 (pasek z restartem) lub 36 (lista). Pobierz normalne i tekstowe przy użyciu stałego wyszukiwania tablicowego na podstawie SV_VertexID w swoim module cieniującym wierzchołki.
Oznacza to, że nie musisz nawet umieszczać tekstów ani normałów w buforze wierzchołków, co zapewni jeszcze więcej oszczędności pamięci.
Idąc dalej, nadal możesz przejść do 24 wierzchołków na kostkę, ale także użyć instancji. Każda kostka miałaby stały rozmiar w buforze wierzchołków (1x1x1) i miałbyś współczynnik skalowania i pozycję (zakładając, że twoje kostki się nie obracają, a jeśli macie, to macierz) jako dane dla instancji. W przypadku nieobrotowego jednorazowy koszt wynosi 24 wierzchołki, ale wtedy każda kostka potrzebuje tylko 6 pływaków, aby w pełni określić. W obrotowej obudowie patrzysz na 16 liczb zmiennoprzecinkowych, ale nawet to jest znaczną oszczędnością (w tym przypadku bardziej prawdopodobne jest wąskie gardło po stronie procesora w przypadku transformacji macierzowych - w przypadku nieobrotowej obudowy budującej matrycę w locie w twój moduł cieniujący wierzchołki - nawet jeśli jest zrobiony dla jednego wierzchołka, jest tak głupio szybki, że nawet nie musisz się tym martwić).
W przypadku tekstur na twarz wystarczy użyć tablicy tekstur. Musisz oczywiście upewnić się, że każda taka tekstura w tablicy ma ten sam rozmiar, i nadal będziesz musiał przerwać bieżącą partię, jeśli sama tablica musi się zmienić, ale w przeciwnym razie dobrze sobie poradzi. Dodaj trzeci tekstowy tekst do definicji wierzchołka, który określa plasterek tablicy do użycia dla każdej twarzy.
Nie potrzebujesz GS z tym i powinien on działać szybciej niż przy użyciu jednego, ponieważ włączenie etapu modułu cieniującego geometrię spowoduje dodatkowe własne obciążenie.
W swoim silniku mam kod porównawczy, który po prostu rysuje kilka kostek za pomocą tej metody, i mogę łatwo przeżuć ponad 300 000 kostek, wciąż czyszcząc 60 klatek na sekundę na stosunkowo niskiej jakości GPU i nie robiąc nic innego, aby zoptymalizować proces . Wprawdzie nie jestem ich oświetleniem ani teksturowaniem, ale mam włączone mieszanie alfa, wyłączone wygładzanie tła i ogólnie równoważy to z moją częścią „nie robienia niczego innego w celu optymalizacji”, więc powinno dać ci rozsądne wyobrażenie o rodzaju boisko można uderzyć tą metodą.
źródło
Myślę, że główna optymalizacja, jaką możesz wykonać, polega na tym, że nie każda kostka faktycznie potrzebuje wszystkich 24 wierzchołków . W rzeczywistości jedynymi sześcianami, które potrzebują 24 wierzchołków, są te, które unoszą się w powietrzu, co jest prawdopodobnie rzadkim zjawiskiem.
Zasadniczo generuj quady tylko dla twarzy mających kontakt z powietrzem . Oznacza to, że jeśli dwa sześciany się stykają, nie trzeba generować żadnych wierzchołków dla twarzy, do której się dotykają.
Poniższy obraz pokazuje tę koncepcję, ale w 2D dla łatwiejszego zrozumienia. Na obrazie znajduje się 11 zajętych bloków (reprezentowanych przez wypełnione szare kółka), które normalnie wymagałyby reprezentacji 4 x 11 = 44 krawędzi (4, ponieważ jest to kwadrat, a nie sześcian). Ale jak widać, naprawdę musisz narysować krawędzie tylko wtedy, gdy stykają się z pustym kwadratem, który w tym przypadku ma tylko 8 krawędzi.
Jeśli tak prostemu przykładowi w 2D udało się zmniejszyć 44 krawędzie do 8 krawędzi, wyobraź sobie korzyści w dużym świecie 3D ...
Takie podejście opisano w tym artykule , które polecam przeczytać, mimo że jest skierowane do OpenGL. Koncepcje powinny być jednak dość uniwersalne.
Prawdopodobnie możesz również użyć modułu cieniującego geometrię do generowania wierzchołków w locie na GPU, co eliminuje potrzebę przechowywania ich w pamięci, ale nie mam z tym doświadczenia, ani nie wiem, jak dobrze by to działało w przypadku dużych świat.
źródło