W Three.js możemy po prostu scalić geometrię, aby ograniczyć liczbę wywołań losowania, a tym samym zwiększyć wydajność. W prostym teście z jednym materiałem mogłem narysować 50 000 kostek + cienie @ 60 fps na moim GPU GTX660. Bez scalenia geometrii problem spowodował już 5000 kostek.
Zastanawiam się, jak zachować korzyści wynikające z renderowania każdej siatki sześcianu na własną rękę. Na przykład, jak wybrać siatkę sześcianu, gdy wszystko jest scalone w jedną geometrię? Domyślnie nie jest to oczywiście możliwe.
Czy istnieje jakaś wspólna technika dla tego problemu? W końcu mam wszystkie nierozproszone obiekty siatki nawet po scaleniu. Więc musi być jakiś sposób na wykorzystanie ich do zbierania?
Co chcę robić w pigułce
- SimCity jak gra do nauki
- Każdy dom jest siatką sześcianu
- Chcesz wyrenderować 50 000 domów i mieć możliwość dodawania i usuwania domów
- Wybór domu za pomocą kursora myszy (kompletacja) musi być możliwy
Odpowiedzi:
Ok, rozumiem. Po scaleniu całej geometrii nadal mam pojedyncze siatki w tablicy. Mogę więc po prostu użyć tych siatek do rastrowania, nawet jeśli nie są nawet renderowane. Zajęło mi to trochę czasu, aby to zrozumieć.
Do kompletacji używam tej implementacji oktty: http://threejs.org/examples/#webgl_octree_raycasting
Zmniejsza to liczbę testów przecięcia na aktualizację z 50 000 do ~ 500. Bez oktetu liczba klatek na sekundę znacznie spadnie.
Pomarańczowy kadłub zbierający, który widzisz, jest w rzeczywistości renderowaną siatką (wywołanie +1) ze zmienionym materiałem i zmodyfikowanym rozmiarem.
Myślę, że następnym krokiem jest zaimplementowanie jakiegoś rodzaju partycjonowania mapy. To znaczy, podziel scaloną geometrię na kilka części. Powodem tego jest to, że scalona geometria ma dużą liczbę wierzchołków. Oznacza to, że jeśli przesunę mapę o 99% poza ekran, karta graficzna nadal będzie musiała przetwarzać wszystkie wierzchołki, ponieważ geometria jest nadal widoczna, przynajmniej 1%. Więc jeśli jest rozbity, tylko widoczne fragmenty muszą zostać zrenderowane.
źródło
Aby wybrać, możesz również renderować identyfikatory dla każdej kostki do innego celu renderowania i po prostu sprawdź, jaka wartość identyfikatora znajduje się na kursorze. Zaletą jest to, że kompletacja jest idealna w pikselach i działa skutecznie również w przypadku bardziej złożonej geometrii.
Jeśli wszystkie obiekty mają tę samą geometrię, możesz użyć renderowania instancji. Jeden strumień określa geometrię, podczas gdy inny określa właściwości na wystąpienie (np. Transformacja). W celu eliminacji frustum należy zbudować strumień instancji dla każdej ramki na podstawie testu widoczności. Jeśli masz dużą liczbę obiektów, możesz je umieścić w luźnej oktecie lub w celu przyspieszenia ubijania.
źródło
Nie jestem pewien co do szczegółów pliku Three.js, ale w ogóle przychodzą mi na myśl dwa możliwe świnie wydajnościowe OpenGL:
źródło
Innym podejściem, jakie możesz zastosować, jest wbudowanie atrybutu wierzchołka do geometrii i umieszczenie logiki podświetlania w module cieniującym fragmenty. Jest to niezwykle przydatne, gdy nie chcesz mieć dwóch kopii danych w pamięci, a będziesz mieć większą kontrolę nad sposobem realizacji wyróżnienia.
źródło