Wiadomości o usługach

Optymalizacja wydajności Androida XR za pomocą Unity

Czas czytania: 6 minut
Luke Hopkins
Inżynier ds. relacji z deweloperami, Android

Samsung Galaxy XR jest już dostępny z Androidem XR! Ten post na blogu jest częścią tygodnia poświęconego Androidowi XR, w ramach którego udostępniamy materiały – posty na blogu, filmy, przykładowy kod i inne – które pomogą Ci poznać Androida XR, tworzyć aplikacje na tę platformę i przygotowywać je do działania na niej.  

W tym tygodniu firma Samsung wprowadziła na rynek Galaxy XR, urządzenie stworzone we współpracy z Google i Qualcomm. To ekscytujący czas dla deweloperów. Chcemy pomóc Ci w osiągnięciu jak najlepszej wydajności aplikacji XR.

Słaba wydajność gier i aplikacji na urządzeniach innych niż XR może być frustrująca dla użytkownika, ale w świecie XR wydajność nie jest tylko opcjonalna, ale ma fundamentalne znaczenie dla sukcesu aplikacji. Jeśli w XR nie osiągniesz docelowej liczby klatek na sekundę, może to spowodować znacznie poważniejsze problemy, takie jak choroba lokomocyjna. 

Z tego przewodnika dowiesz się, jakie optymalizacje wydajności są niezbędne podczas tworzenia aplikacji na Androida XR. Dowiesz się, które funkcje zapewniają największy wzrost wydajności, kiedy ich używać i jak ze sobą współpracują, aby pomóc Ci osiągnąć docelową liczbę klatek na sekundę.

Nasze cele: 

  • Minimalna: 72 klatki na sekundę (zgodnie z naszymi wskazówkami dotyczącymi jakości odtwarzania).
  • Opcjonalnie: 90 kl./s z budżetem 11 ms na klatkę

Więcej informacji o tym, dlaczego ważne jest utrzymywanie tak wysokiej liczby klatek na sekundę, znajdziesz w naszych wytycznych dotyczących wydajności.   

Funkcje wydajnościowe XR

Zaczniemy od 2 funkcji związanych z wydajnością w przypadku XR: renderowania z ogniskowaniem i próbkowania Vulkan. 

Renderowanie foveated

Renderowanie foveated to optymalizacja, która ma 2 tryby. Pierwszy to tryb statyczny, w którym środek ekranu jest renderowany w wyższej rozdzielczości, a rozdzielczość stopniowo się obniża wraz z oddalaniem się od środka.

Drugi to tryb śledzenia wzroku, który renderuje w pełnej szczegółowości obszar, na który patrzysz, a jednocześnie zmniejsza jakość wyświetlaną na obrzeżach. Naśladuje ona sposób, w jaki działa ludzki wzrok – widzimy szczegóły tylko w obszarze, na którym się skupiamy.

Renderowanie z ogniskowaniem znacznie zmniejsza obciążenie procesora graficznego bez pogarszania postrzeganej jakości obrazu. Zaletą renderowania z ogniskowaniem jest to, że użytkownicy nie zauważą obniżonej jakości w peryferyjnym polu widzenia, ale GPU z pewnością odnotuje wzrost wydajności.

Wyobraź sobie, że tworzysz muzeum z złożonymi artefaktami 3D. Bez renderowania foveated trudno byłoby utrzymać 90 klatek na sekundę podczas renderowania wszystkiego w „polu widzenia”. Dzięki renderowaniu foveated możesz zachować szczegóły o wysokiej liczbie wielokątów w miejscu, na które patrzy użytkownik, ale środowisko w tle jest renderowane w niższej jakości. Użytkownicy nie zauważą różnicy, ale Ty będziesz mieć więcej miejsca na dodanie szczegółów do sceny.

Podpróbkowanie Vulkan

Podpróbkowanie Vulkan to najlepszy przyjaciel renderowania foveated. Renderowanie z ogniskowaniem decyduje o tym, co ma być renderowane na różnych poziomach jakości, a podpróbkowanie Vulkan obsługuje wydajne renderowanie różnych poziomów jakości za pomocą map gęstości fragmentów.

W połączeniu z renderowaniem z ogniskowaniem Vulkan Subsampling zapewnia dodatkowe 0, 5 ms wydajności. Pomaga też wygładzić poszarpane krawędzie w peryferyjnym polu widzenia, dzięki czemu obraz jest wyraźniejszy.

Na przykład w symulatorze lotu, w którym użytkownicy skupiają się na przyrządach i elementach sterujących, połączenie renderowania z ogniskowaniem wzroku z podpróbkowaniem Vulkan oznacza, że szczegółowe elementy sterujące są renderowane w wysokiej rozdzielczości, ale struktura kokpitu na obrzeżach wykorzystuje mniej zasobów. Dodatkowe 0,5 ms nie wydaje się dużą wartością, ale może zadecydować o tym, czy w reklamie zmieści się dodatkowy element interaktywny, czy też w trakcie intensywnych momentów będą pomijane klatki.

Funkcje GPU w przypadku złożonych scen

Oprócz renderowania z ogniskowaniem i podpróbkowania Vulkan istnieją też funkcje GPU, które zmniejszają niepotrzebne obciążenie dzięki inteligentnemu tworzeniu instancji i usuwaniu. Są one szczególnie skuteczne w przypadku złożonych scen z powtarzającą się geometrią lub znacznym zasłanianiem.

GPU Resident Drawer

Moduł renderowania rezydentów GPU automatycznie wykorzystuje instancjonowanie GPU, aby zmniejszyć liczbę wywołań rysowania i zwolnić czas przetwarzania procesora. Zamiast więc informować GPU o każdym obiekcie z osobna, CPU grupuje podobne obiekty.

Ta funkcja jest najbardziej skuteczna w przypadku dużych scen z powtarzającymi się siatkami, takimi jak drzewa w lesie, meble w biurowcu lub rekwizyty rozrzucone po całym otoczeniu.

Wyobraź sobie scenę w lesie z 200 drzewami, które mają tę samą siatkę bazową. Bez funkcji GPU Resident Drawer masz 200 wywołań rysowania, które obciążają procesor graficzny, a tym samym zwalniają procesor. Gdy włączysz tę funkcję, procesor graficzny będzie inteligentnie tworzyć instancje tych drzew, co powinno zmniejszyć liczbę wywołań rysowania do 5–10. To ogromna oszczędność mocy GPU, którą możesz wykorzystać na logikę rozgrywki lub obliczenia fizyczne.

GPU Occlusion Culling

GPU Occlusion Culling używa GPU zamiast CPU do identyfikowania i pomijania renderowania ukrytych obiektów. Automatycznie wykrywa, co jest zasłonięte (ukryte) za innymi obiektami, dzięki czemu nie marnujesz mocy procesora graficznego na elementy, których użytkownik nie widzi.

Ta funkcja jest szczególnie przydatna w przestrzeniach wewnętrznych z wieloma pomieszczeniami, gęstych środowiskach lub scenach architektonicznych, w których ściany, podłogi i obiekty naturalnie blokują widok.

Załóżmy na przykład, że tworzysz funkcję dla domu z wieloma pomieszczeniami. Gdy użytkownik jest w salonie, po co marnować cykle GPU na renderowanie w pełni szczegółowej kuchni, która jest całkowicie ukryta za ścianą? GPU Occlusion Culling automatycznie pomija renderowanie ukrytych obiektów, dzięki czemu masz większy budżet wydajności na to, co jest faktycznie widoczne.

Monitorowanie skuteczności

Nie wystarczy tylko korzystać z tych funkcji. Musisz też mierzyć skuteczność optymalizacji, aby określać ich wpływ i sprawdzać, czy wprowadzone zmiany rzeczywiście działają.

Performance Metrics API

Interfejs Performance Metrics API umożliwia monitorowanie w czasie rzeczywistym wykorzystania pamięci, wydajności procesora i wydajności GPU przez aplikacje. Zawiera ona kompleksowe dane z warstw kompozytora i środowiska wykonawczego, dzięki czemu możesz dokładnie zobaczyć, co dzieje się w Twojej aplikacji.

Przed wprowadzeniem zmian ustal punkt odniesienia, zastosuj optymalizację, zmierz jej wpływ i powtórz te czynności. Dzięki temu podejściu opartemu na danych wiesz, że faktycznie zwiększasz skuteczność, a nie tylko zgadujesz.

Przed włączeniem renderowania z ogniskowaniem czas renderowania klatki przez GPU może wynosić 13 ms, czyli więcej niż 11 ms. Włącz renderowanie z ogniskowaniem, ponownie zmierz czas i miejmy nadzieję, że spadnie on do 9 ms. To 4 ms dodatkowego czasu, który możesz wykorzystać na dodanie większej liczby szczegółów do sceny, poprawę jakości wizualnej w innych miejscach lub po prostu zapewnienie płynniejszego działania w przypadku szerszego zakresu treści.

Bez tych danych optymalizacja jest prowadzona na ślepo. Interfejs Performance Metrics API dostarcza prawdziwych informacji o tym, co faktycznie pomaga w Twoim konkretnym przypadku użycia.

Debuger klatek

Debuger klatek to wbudowane narzędzie Unity, które pozwala dokładnie zrozumieć, jak scena jest renderowana, klatka po klatce. Wyświetla sekwencję wywołań rysowania i umożliwia przechodzenie przez nie krok po kroku, aby sprawdzić, czy optymalizacje działają prawidłowo.

Chcesz sprawdzić, czy narzędzie SRP Batcher działa? W narzędziu Frame Debugger poszukaj wpisów „RenderLoopNewBatcher”. Sprawdzanie, czy moduł GPU Resident Drawer prawidłowo przetwarza zadania wsadowo. Znajdź wpisy „Hybrid Batch Group”. Te wizualne potwierdzenia pomogą Ci sprawdzić, czy ustawienia optymalizacji są rzeczywiście stosowane.

Przejdź przez pierwsze 50 wywołań rysowania w scenie. Jeśli widzisz podobne obiekty rysowane pojedynczo zamiast w grupach, oznacza to, że instancjonowanie lub grupowanie nie działa prawidłowo. Debuger klatek sprawia, że te problemy są od razu widoczne, dzięki czemu możesz je rozwiązać.

Dodatkowe optymalizacje

Oprócz optymalizacji, o których wspomnieliśmy powyżej, w naszym pełnym przewodniku po skuteczności znajdziesz też kilka innych dodatkowych optymalizacji. Oto krótkie podsumowanie:

  • Ustawienia URP: wyłącz HDR i przetwarzanie końcowe na urządzeniach mobilnych XR. Te funkcje mają minimalny wpływ wizualny w porównaniu z kosztem wydajności na urządzeniach mobilnych, więc uzyskasz mierzalne zwiększenie wydajności przy ledwo zauważalnych różnicach wizualnych.
  • SRP Batcher: zmniejsza obciążenie procesora w scenach z wieloma materiałami korzystającymi z tego samego wariantu shadera. Minimalizując zmiany stanu renderowania między wywołaniami rysowania, możesz znacznie skrócić czas procesora poświęcony na renderowanie.
  • Częstotliwość odświeżania wyświetlacza: dynamicznie dostosowywana w zakresie od 72 do 90 klatek na sekundę w zależności od złożoności sceny. Obniż liczbę klatek na sekundę podczas złożonych sekwencji, aby zachować stabilność, a następnie zwiększ ją w prostszych momentach, aby zapewnić płynną interakcję.
  • Tekstury głębi/nieprzezroczyste: wyłącz te opcje, chyba że są potrzebne do efektów cieniowania. Powodują one niepotrzebne operacje kopiowania na GPU, które marnują wydajność bez korzyści dla większości aplikacji.
  • Skala renderowania URP: to ustawienie umożliwia renderowanie w niższej rozdzielczości, aby zwiększyć wydajność, lub zwiększanie rozdzielczości renderowania, aby poprawić jakość obrazu.

Szczegółowe instrukcje dotyczące tych i innych optymalizacji znajdziesz w naszym pełnym przewodniku po optymalizacji wydajności Unity na Androida XR.

Podsumowanie

Wydajność aplikacji XR to nie tylko kwestia techniczna. To różnica między komfortowym i angażującym doświadczeniem a takim, które wywołuje u użytkowników mdłości lub dyskomfort. Opisane przez nas optymalizacje to zestaw narzędzi, które pomogą Ci osiągnąć krytyczne wartości liczby klatek na sekundę na najnowszych urządzeniach XR.

Oto Twój plan:

  1. Zacznij od renderowania z ogniskowaniem i próbkowania Vulkan. Te funkcje przeznaczone dla XR zapewniają natychmiastowe i wyraźne oszczędności w zakresie GPU.
  2. Jeśli masz złożone sceny z powtarzającą się geometrią lub przestrzenie wewnętrzne, dodaj funkcje GPU Resident Drawer i Occlusion Culling.
  3. Monitoruj wszystko za pomocą interfejsu Performance Metrics API, aby mieć pewność, że wprowadzane zmiany rzeczywiście pomagają.
  4. Dodatkowe optymalizacje URP, które zwiększają potencjał wydajności

Kluczowe jest ciągłe mierzenie i wprowadzanie zmian. Nie każda optymalizacja przyniesie korzyści wszystkim projektom w równym stopniu, dlatego użyj interfejsu Performance Metrics API, aby uzyskać jasny obraz tego, co faktycznie pomaga w Twoim konkretnym przypadku użycia.

Co dalej: rozwijanie umiejętności

Chcesz dowiedzieć się więcej? Zapoznaj się z tymi materiałami:

  • Przewodnik po wydajności Unity na Androidzie XR – szczegółowe instrukcje implementacji wszystkich funkcji opisanych tutaj.
  • Pierwsze kroki z Unity i Androidem XR – skonfiguruj środowisko programistyczne i  zacznij tworzyć aplikacje.
  • Dokumentacja dla deweloperów Androida XR – obszerne przewodniki po wszystkich funkcjach Androida XR.
Autor:

Czytaj dalej