Tworzę grę w stylu low poly. Mam teren z odrobiną wody i chcę dużo drzew; W tej chwili mam 10 000 drzew. Każde drzewo składa się z nie więcej niż 200 trójkątów, więc nie są zbyt obciążające.
Głównym problemem jest to, że są jeziora, a jeziora są dość duże. Po drugiej stronie jeziora nie widać właściwie żadnych drzew, a to wygląda naprawdę źle, szczególnie gdy idziesz tam i nagle pojawiają się drzewa.
Aby to naprawić, muszę zwiększyć odległość między drzewami, abyś mógł zobaczyć przyzwoitą liczbę drzew po drugiej stronie jeziora, ale to zmniejsza wydajność do 40-50 klatek na sekundę, a w grze nie ma już nic więcej. Używam GTX 1080, jeśli to pomaga.
Co mogę zrobić, aby moja gra działała szybciej z większą liczbą drzew?
unity
performance
terrain
mr-matt
źródło
źródło
Odpowiedzi:
Istnieje kilka rzeczy, które możesz zrobić, aby zwiększyć wydajność rysowania.
Powiedziałeś, że byli dość daleko. Możesz użyć LOD, aby zmniejszyć liczbę wierzchołków tych drzew, a tym samym skrócić czas potrzebny na przejście przez wszystkie narysowane wierzchołki. Chociaż najprawdopodobniej nie jest to kwestia pod ręką (GTX1080 z zaledwie 10k drzewkami po 200 tris każdy, mizerne liczby dla GPU), nadal go uwzględniam. Billboard jest skutecznym narzędziem dla najniższego poziomu LOD, ponieważ jest to zasadniczo płaska płaszczyzna zawsze zwrócona w stronę kamery z renderowanym obrazem drzewa. Traci poczucie głębi, dlatego jest dobre na najniższym poziomie, ponieważ gracz najprawdopodobniej nie zauważy różnicy.
Czy włączyłeś grupowanie ? Dozowanie dynamiczne odbywa się zwykle automatycznie, jeśli liczba wierzchołków siatek jest dość niska. Partię statyczną można również wypróbować, ustawiając drzewa statycznie, zaznaczając pole wyboru w edytorze jedności na obiekcie nadrzędnym. To nie działa dobrze z animowanymi obiektami. Aby obiekty działały, potrzebujesz obiektów, które mają udostępniony materiał.
Niestandardowe grupowanie pozwala kontrolować renderowanie przez samodzielne generowanie fragmentów, zamiast pozwolić jedności sobie z tym poradzić, a także umożliwia grupowanie w większe siatki. Dokonuje tego łatwo Mesh.CombineMeshes . To również nie działa dobrze z animowanymi obiektami. Aby obiekty działały, potrzebujesz obiektów, które mają udostępniony materiał. Prawdopodobnie chcesz podzielić swój świat na kilka części i tworzyć z nich partie. To, jak powinny być generowane te fragmenty, zależy od tego, jak kamera porusza się po świecie.
Włącz instancję na modułach cieniujących. Instancja umożliwia silnikowi rysowanie wielu obiektów (z tą samą siatką) za pomocą tylko jednego wywołania rysowania. Aby to zadziałało, obiekty muszą mieć wspólną siatkę i udostępniony moduł cieniujący. Materiał może się różnić, ale moduł cieniujący musi obsługiwać wszystkie różne zmienne właściwości.
Aby silnik mógł lepiej tworzyć instancyjne partie renderowania, prawdopodobnie chcesz zgrupować te same siatki w scenie. Również gra z kolejką renderowania materiału daje dobre wyniki, jeśli jedna siatka ma zawsze ten sam materiał. Podczas opracowywania gry mobilnej, nad którą obecnie pracuję, wykorzystałem ją do zmniejszenia liczby wezwań o ponad połowę w mojej scenie testowej. Również od Unity 5.6 upewnij się, że zaznaczyłeś pole
Enable Instancing
wyboru w materiale.Ogółem utrzymuj połączenia telefoniczne i połączenia SetPass. Są to surowe wezwania twojego GPU do rysowania rzeczy i mają one duży narzut. Zmniejszanie przeciągnięć (co to jest tworzenie partii i tworzenie instancji) zwiększy ogólną wydajność twojego procesora, ponieważ jest to wymagane o wiele mniej oczekiwania. Wywołania SetPass są zmianami w obecnych modułach cieniujących, więc jeśli masz wiele różnych materiałów, będziesz mieć wiele wywołań SetPass, które również powodują, że procesor trochę czeka.
Jeśli Twoja scena jest ogromna, a Twój procesor poświęca czas na przejrzenie wszystkich obiektów na scenie, spróbuj zmniejszyć obiekty na scenie. Zgrupuj niektóre drzewa zamiast umieszczać je osobno i umieść je jako jeden obiekt. Upewnij się także, że nie przenosisz drzew ani obiektów nadrzędnych, ponieważ to powoduje, że Unity odrzuca buforowane transformacje i ponownie oblicza całe drzewo sceny.
Jeśli twoja scena jest ogromna, a twój czas procesora nadal dotyczy głównie Unity przechodzącej przez drzewo scen, aby tworzyć listy do renderowania wszystkich obiektów, jedną rzeczą, którą możesz zrobić, to nie pozwolić Unity obsługiwać renderowania. Jeśli masz lepszy sposób na śledzenie obiektów rysowalnych, możesz użyć CommandBuffer.DrawMeshInstanced lub Graphics.DrawMeshInstanced, aby narysować je ręcznie. Nie będę szczegółowo omawiał tego tematu, ponieważ jest on o wiele bardziej zaawansowany i polega na wykańczaniu siebie i innych.
W przypadku, gdy grupowanie statyczne lub dynamiczne nie działa poprawnie (co widać po sprawdzeniu debuggera ramki), musisz upewnić się, że rzeczywiście korzystasz z udostępnionego materiału i nie tworzysz kopii materiału przypadkowo podczas wywoływania
meshRenderer.material
. Zadzwonienie.material
spowoduje wykonanie kopii twoich materiałów i przerwanie partii. Użyj.sharedMaterial
zamiast tego.Od Unity 5.6 możesz używać Debuggera Ramek, aby ustalić, dlaczego niektóre przeciągnięcia nie były wsadowe z poprzednimi przeciągnięciami. Będzie to bardzo pomocne podczas próby ograniczenia przeciągnięć w grze.
Instancje mają następujące zalety w porównaniu do grupowania statycznego / dynamicznego / niestandardowego:
Wadą tego jest raczej nowa funkcja w Unity i może być nieco niestabilna. Również starsze lub GPU urządzeń mobilnych niekoniecznie obsługują instancje.
źródło
Ok, więc problem polegał po prostu na tym, że nie używałem wstępnie obliczonego GI w czasie rzeczywistym. Sprawdziłem to jakiś czas temu, ale nie przyniosło to natychmiastowego efektu, więc zostawiłem to i zapomniałem o tym, a czas przetwarzania oświetlenia też był tak długi. Jednak właśnie skończył to przetwarzać i moje słowo, mój fps skoczył trzykrotnie. Więc na razie zostawię to i w przyszłości upewnij się, że zawsze używam GI w czasie rzeczywistym!
Jeśli nadal jest coś, co mógłbym zrobić, aby jeszcze bardziej poprawić wydajność, proszę dać mi znać, byłbym bardzo wdzięczny!
źródło