kilka podstawowych informacji, które przygotują Cię na spektrum doznań: od rzeczywistości wirtualnej po rzeczywistość rozszerzoną i wszystko pomiędzy.
W Chrome 79 pojawiły się wciągające treści. Interfejs WebXR Device API umożliwia korzystanie z rzeczywistości wirtualnej, a w Chrome 81 pojawiła się obsługa rzeczywistości rozszerzonej. Zaktualizowany interfejs GamePad API umożliwia zaawansowane sterowanie w VR. Wkrótce inne przeglądarki będą obsługiwać te specyfikacje, w tym Firefox Reality, Oculus Browser, Edge i przeglądarka Helio firmy Magic Leap.
Z tego artykułu rozpoczyna się seria poświęcona rzeczywistości rozszerzonej. W tej części omawiamy konfigurowanie podstawowej aplikacji WebXR oraz wchodzenie do sesji XR i z niej wychodzenie. W kolejnych artykułach omówimy pętlę ramki (główny element interfejsu WebXR), specyfikę rzeczywistości rozszerzonej oraz interfejs WebXR Hit Test API, który służy do wykrywania powierzchni w sesji AR. O ile nie określono inaczej, wszystko, o czym piszę w tym i kolejnych artykułach, dotyczy zarówno AR, jak i VR.
Czym jest immersywna sieć?
Chociaż do opisania wciągających doświadczeń używamy 2 terminów – rzeczywistości rozszerzonej i wirtualnej – wiele osób traktuje je jako spektrum od pełnej rzeczywistości do całkowicie wirtualnej, z różnymi stopniami immersji pośrodku. Litera „X” w XR ma odzwierciedlać to podejście, ponieważ jest rodzajem zmiennej algebraicznej, która oznacza wszystko w zakresie doświadczeń w środowisku.
Przykłady doświadczeń w pełni wykorzystujących możliwości VR:
- Gry
- Filmy 360°
- tradycyjne filmy 2D (lub 3D) prezentowane w realistycznym otoczeniu;
- Kupowanie domu
- Wyświetlanie produktów w domu przed zakupem
- Wciągająca sztuka
- Coś fajnego, o czym nikt jeszcze nie pomyślał
Pojęcia i zastosowanie
Wyjaśnię kilka podstawowych kwestii związanych z korzystaniem z interfejsu WebXR Device API. Jeśli potrzebujesz więcej informacji, zapoznaj się z próbkami WebXR opracowanymi przez grupę roboczą Immersive Web lub z stale rosnącą liczbą materiałów referencyjnych na stronie MDN. Jeśli znasz wcześniejsze wersje interfejsu WebXR Device API, zapoznaj się z całymi materiałami. Wprowadzono zmiany.
Kod w tym artykule jest oparty na minimalnym przykładzie grupy roboczej dotyczącej rozszerzonej rzeczywistości (demo, źródło), ale został zmodyfikowany w celu zwiększenia przejrzystości i prostoty.
W ramach tworzenia specyfikacji WebXR opracowano środki bezpieczeństwa i prywatności, które chronią użytkowników. W związku z tym implementacje muszą spełniać określone wymagania. Strona internetowa lub aplikacja musi być aktywna i aktywna, aby móc poprosić widza o coś poufnego. Strony internetowe lub aplikacje muszą być wyświetlane przez HTTPS. Interfejs API został zaprojektowany tak, aby chronić informacje uzyskane z czujników i kamer, których potrzebuje do działania.
Prośba o sesję
Włączenie sesji XR wymaga gestu użytkownika. Aby to zrobić, użyj funkcji wykrywania, aby przetestować XRSystem
(za pomocą navigator.xr
), a potem zadzwoń do XRSystem.isSessionSupported()
. Pamiętaj, że w Chrome w wersjach 79 i 80 obiekt XRSystem
miał nazwę XR
.
W przykładzie poniżej wskazałem, że chcę utworzyć sesję rzeczywistości wirtualnej z typem sesji 'immersive-vr'
. Inne typy sesji to 'immersive-ar'
i 'inline'
. Sesja wstawiona służy do prezentowania treści w kodzie HTML i jest używana głównie w przypadku treści teaserowych. Przykład zajęcia z rozszerzoną rzeczywistością to potwierdza. Omówię to w następnym artykule.
Gdy wiem, że sesje rzeczywistości wirtualnej są obsługiwane, włączam przycisk, który pozwala mi uzyskać gest użytkownika.
if (navigator.xr) {
const supported = await navigator.xr.isSessionSupported('immersive-vr');
if (supported) {
xrButton.addEventListener('click', onButtonClicked);
xrButton.textContent = 'Enter VR';
xrButton.enabled = supported; // supported is Boolean
}
}
Po włączeniu przycisku czekam na zdarzenie kliknięcia, a potem proszę o sesję.
let xrSession = null;
function onButtonClicked() {
if (!xrSession) {
navigator.xr.requestSession('immersive-vr')
.then((session) => {
xrSession = session;
xrButton.textContent = 'Exit XR';
onSessionStarted(xrSession);
});
} else {
xrSession.end();
}
}
Zwróć uwagę na hierarchię obiektów w tym kodzie. Przechodzi z navigator
do xr
do wystąpienia XRSession
. W wcześniejszych wersjach interfejsu API skrypt musiał poprosić o urządzenie, zanim poprosił o sesję. Teraz urządzenie jest pobierane w ramach niejawnego pobierania.
Dołączanie do sesji
Po uzyskaniu sesji muszę ją rozpocząć i wejść do niej. Najpierw jednak muszę skonfigurować kilka rzeczy. Sesja wymaga modułu obsługi zdarzenia onend
, aby można było zresetować aplikację lub stronę internetową po wyjściu użytkownika.
Do rysowania sceny potrzebuję też elementu <canvas>
. Musi to być kontekst WebGLRenderingContext lub WebGL2RenderingContext zgodny z XR.
Wszystkie rysunki są tworzone za pomocą tych obiektów lub platformy opartej na WebGL, takiej jak Three.js.
Teraz, gdy mam miejsce do rysowania, potrzebuję źródła treści, na których będę rysować. W tym celu utworzyłem instancję klasy XRWebGLLayer
. Powiązanie go z płótnem odbywa się przez wywołanie funkcji XRSession.updateRenderState()
.
Gdy jestem w sesji, potrzebuję sposobu na określenie, gdzie znajdują się obiekty w wirtualnej rzeczywistości. Potrzebuję miejsca na odniesienie. 'local-floor'
przestrzeń odniesienia to przestrzeń, w której początek układu współrzędnych znajduje się w pobliżu widza, a oś Y ma wartość 0 na poziomie podłogi i nie powinna się przesuwać. Istnieją inne typy przestrzeni referencyjnych, ale jest to bardziej skomplikowany temat, niż mogę tu omówić. Przechowuję przestrzeń referencyjną w zmiennej, ponieważ będę jej potrzebować, gdy będę rysować na ekranie.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
let canvas = document.createElement('canvas');
webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
});
xrSession.requestReferenceSpace('local-floor')
.then((refSpace) => {
xrRefSpace = refSpace;
xrSession.requestAnimationFrame(onXRFrame);
});
}
Po uzyskaniu przestrzeni odniesienia wywołuję funkcję XRSession.requestAnimationFrame()
.
To początek wyświetlania treści wirtualnych, który odbywa się w ramach pętli ramek.
Uruchamianie pętli ramek
Ramka pętli to nieskończona pętla kontrolowana przez użytkownika, w której treści są wielokrotnie wyświetlane na ekranie. Treści są wyświetlane w oddzielnych blokach zwanych klatkami. Kolejność klatek tworzy iluzję ruchu. W przypadku aplikacji VR liczba klatek na sekundę może wynosić od 60 do 144. AR na Androida działa z częstotliwością 30 klatek na sekundę. Kod nie powinien zakładać żadnej konkretnej liczby klatek na sekundę.
Podstawowy proces pętli ramki:
- Zadzwoń do firmy
XRSession.requestAnimationFrame()
. W odpowiedzi na to klient użytkownika wywołujeXRFrameRequestCallback
, który został przez Ciebie zdefiniowany. - W funkcji wywołania zwrotnego:
- Zadzwoń ponownie do
XRSession.requestAnimationFrame()
. - Uzyskaj pozę widza.
- Przekazywanie (bindowanie)
WebGLFramebuffer
zXRWebGLLayer
doWebGLRenderingContext
. - Przetwarzaj każdy obiekt
XRView
, pobierając z niego elementXRViewport
z obiektuXRWebGLLayer
i przekazując go do obiektuWebGLRenderingContext
. - Rysowanie czegoś w ramce bufora.
- Zadzwoń ponownie do
Pozostała część tego artykułu opisuje krok 1 i część kroku 2, czyli konfigurowanie i wywoływanie funkcji XRFrameRequestCallback
. Pozostałe elementy kroku 2 są omawiane w części II.
Zwracanie wywołania zwrotnego XRFrameRequestCallback
XRFrameRequestCallback
definiujesz samodzielnie. Przyjmuje 2 parametry: instancję DOMHighResTimeStamp
i XRFrame
. Obiekt XRFrame
zawiera informacje potrzebne do renderowania pojedynczego klatki na wyświetlaczu. Argument DOMHighResTimeStamp
jest przeznaczony do użycia w przyszłości.
Zanim zrobię cokolwiek innego, poproszę o kolejną klatkę animacji. Jak już wspomnieliśmy, czas wyświetlania klatek jest określany przez klienta użytkownika na podstawie sprzętu. Żądanie następnej klatki jako pierwszej zapewnia, że pętla klatki będzie kontynuowana, jeśli podczas wywołania zwrotnego wystąpi błąd.
function onXRFrame(hrTime, xrFrame) {
let xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
// Render a frame.
}
W tym momencie nadszedł czas, aby narysować coś dla widza. To temat na część II. Zanim to zrobimy, pokażę Ci, jak zakończyć sesję.
Zakończ sesję
Sesja wrażeń może zostać zakończona z różnych powodów, m.in. przez Twój kod wywołujący funkcję XRSession.end()
. Inne przyczyny to odłączenie zestawu słuchawkowego lub przejęcie nad nim kontroli przez inną aplikację. Dlatego aplikacja o dobrym zachowaniu powinna monitorować zdarzenie end
. W takim przypadku odrzuć sesję i powiązane z nią obiekty renderowania. Zakończonej sesji w trybie immersyjnym nie można wznowić. Aby ponownie wejść do trybu pełnoekranowego, aplikacja musi rozpocząć nową sesję.
Pamiętasz z Wchodzenie do sesji, że podczas konfiguracji dodałem element obsługi zdarzenia onend
.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
// More setup…
}
W obiekcie funkcji obsługi zdarzenia przywróć stan aplikacji sprzed rozpoczęcia sesji przez użytkownika.
function onSessionEnded(event) {
xrSession = null;
xrButton.textContent = 'Enter VR';
}
Podsumowanie
Nie omówiliśmy wszystkich kwestii związanych z tworzeniem aplikacji XR lub AR w internecie. Mam nadzieję, że udało mi się przekazać Ci wystarczająco dużo informacji, abyś mogła samodzielnie zrozumieć kod i zacząć eksperymentować. W następnym artykule wyjaśnię, czym jest pętla ramki, czyli proces wyświetlania treści na ekranie.
Zdjęcie: JESHOOTS.COM z Unsplash