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 Androida

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, czyli gogle stworzone we współpracy z Google i Qualcomm. To ekscytujący czas dla deweloperów, dlatego chcemy pomóc Ci w osiąganiu jak najlepszych wyników w przypadku 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. 

W tym przewodniku przedstawimy najważniejsze optymalizacje wydajności, które musisz znać, aby tworzyć aplikacje na Androida XR. Dowiesz się, które funkcje zapewniają największy wzrost wydajności, kiedy ich używać i jak współpracują ze sobą, aby pomóc Ci osiągnąć docelową liczbę klatek na sekundę.

Oto do czego dążymy: 

  • 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. Działa ona podobnie do ludzkiego wzroku – 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 foveated jest to, że użytkownicy nie zauważą obniżonej jakości w peryferyjnym polu widzenia, ale procesor graficzny z pewnością odnotuje poprawę wydajności.

Wyobraź sobie, że tworzysz muzeum z złożonymi artefaktami 3D. Bez renderowania foveated trudno byłoby utrzymać 90 klatek na sekundę przy próbie 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 określa, 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 intensywnych momentach będą gubione 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ł rezydentny GPU automatycznie używa instancjonowania 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, w gęstych środowiskach lub w 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ęcej budżetu wydajności w przypadku tego, co jest faktycznie widoczne.

Monitorowanie skuteczności

Samo korzystanie z tych funkcji nie wystarczy. 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 procesora graficznego przez aplikacje. Dostarcza on 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. To podejście oparte na danych oznacza, że 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 niemożliwa. 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 do debugowania klatek poszukaj wpisów „RenderLoopNewBatcher”. Sprawdzanie, czy szuflada rezydentna GPU 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, że podobne obiekty są rysowane pojedynczo, a nie w grupach, oznacza to, że tworzenie instancji lub grupowanie nie działa prawidłowo. Debuger klatek od razu uwidacznia te problemy, 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 wzrosty 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 dostosowuje się 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 obniżają 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 w wyższej rozdzielczości, aby poprawić jakość obrazu.

Szczegółowe instrukcje dotyczące tych i innych optymalizacji znajdziesz w naszym pełnym przewodniku po 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 specyficzne 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. Poznaj dodatkowe optymalizacje URP, które zwiększą potencjał wydajności

Kluczowe jest ciągłe mierzenie i wprowadzanie zmian. Nie każda optymalizacja przyniesie korzyści w każdym projekcie, dlatego używaj 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