Kilka podstawowych informacji, które przygotują Cię na różne immersyjne doświadczenia: rzeczywistość wirtualną, rzeczywistość rozszerzoną i wszystko pomiędzy nimi.
W Chrome 79 wprowadziliśmy wciągające funkcje w internecie. Interfejs WebXR Device API wprowadza rzeczywistość wirtualną, a obsługa rzeczywistości rozszerzonej pojawi się w Chrome 81. Aktualizacja interfejsu GamePad API rozszerza zaawansowane korzystanie z elementów sterujących na VR. Wkrótce te specyfikacje będą obsługiwane przez inne przeglądarki, m.in. Firefox Reality, Oculus Browser, Edge i Helio od Magic Leap.
Ten artykuł rozpoczyna serię poświęconą internetowi immersyjnemu. W tym odcinku omówimy konfigurowanie podstawowej aplikacji WebXR oraz wchodzenie w sesję XR i wychodzenie z niej. W kolejnych artykułach omówimy pętlę klatek (podstawę działania WebXR), szczegóły dotyczące rzeczywistości rozszerzonej oraz interfejs WebXR Hit Test API, który umożliwia wykrywanie powierzchni w sesji AR. O ile nie zaznaczono inaczej, wszystko, o czym piszę w tym i kolejnych artykułach, dotyczy zarówno AR, jak i VR.
Czym jest internet immersyjny?
Do opisywania immersyjnych doświadczeń używamy dwóch terminów: rzeczywistość rozszerzona i rzeczywistość wirtualna. Wiele osób postrzega je jednak jako spektrum od całkowitej rzeczywistości do całkowitej wirtualności, z różnymi stopniami immersji pomiędzy nimi. Litera „X” w skrócie XR ma odzwierciedlać to podejście, ponieważ jest rodzajem zmiennej algebraicznej, która oznacza wszystko w spektrum immersyjnych doświadczeń.
Przykłady treści immersyjnych:
- Gry
- Filmy 360°
- Tradycyjne filmy 2D (lub 3D) wyświetlane w otoczeniu immersyjnym
- Kupowanie domu
- Wyświetlanie produktów w domu przed zakupem
- Sztuka immersyjna
- Coś fajnego, o czym jeszcze nikt nie pomyślał
Pojęcia i zastosowanie
Wyjaśnię kilka podstawowych kwestii związanych z korzystaniem z interfejsu WebXR Device API. Jeśli potrzebujesz bardziej szczegółowych informacji, zapoznaj się z przykładami WebXR grupy roboczej Immersive Web Working Group lub z rosnącymi materiałami referencyjnymi MDN. Jeśli znasz wcześniejsze wersje interfejsu WebXR Device API, możesz przejrzeć wszystkie te materiały. Wprowadzono zmiany.
Kod w tym artykule bazuje na podstawowym przykładzie opracowanym przez Immersive Web Working Group (demo, źródło), ale został zmodyfikowany dla większej przejrzystości i prostoty.
W ramach tworzenia specyfikacji WebXR opracowaliśmy środki bezpieczeństwa i ochrony prywatności, które mają chronić użytkowników. W związku z tym wdrożenia muszą spełniać określone wymagania. Strona internetowa lub aplikacja musi być aktywna i skupiona, zanim będzie mogła poprosić użytkownika o jakiekolwiek informacje poufne. Strony internetowe lub aplikacje muszą być udostępniane przez HTTPS. Sam interfejs API został zaprojektowany tak, aby chronić informacje uzyskiwane z czujników i kamer, które są mu potrzebne do działania.
Prośba o sesję
Wejście w sesję XR wymaga gestu użytkownika. Aby to zrobić, użyj wykrywania funkcji, aby przetestować XRSystem (za pomocą navigator.xr) i wywołać XRSystem.isSessionSupported(). Pamiętaj, że w Chrome w wersji 79 i 80 obiekt
XRSystem nazywał się XR.
W przykładzie poniżej wskazuję, że chcę sesji w rzeczywistości wirtualnej o typie 'immersive-vr'. Inne typy sesji to 'immersive-ar' i 'inline'. Sesja wbudowana służy do wyświetlania treści w HTML i jest używana głównie w przypadku treści wprowadzających. Pokazuje to przykład Immersive AR
Session. Wyjaśnię to w późniejszym artykule.
Gdy wiem, że sesje rzeczywistości wirtualnej są obsługiwane, włączam przycisk, który umożliwia mi uzyskanie gestu 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 następnie wysyłam prośbę 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. Przenosi się z navigator do xr, a następnie do instancji XRSession. We wczesnych wersjach interfejsu API skrypt musiał zażądać urządzenia przed zażądaniem sesji. Urządzenie jest teraz pozyskiwane niejawnie.
Wpisz sesję
Po uzyskaniu sesji muszę ją rozpocząć i do niej dołączyć. Najpierw muszę jednak
skonfigurować kilka rzeczy. Sesja wymaga modułu obsługi zdarzeń onend, aby można było zresetować aplikację lub stronę internetową po wyjściu użytkownika.
Będę też potrzebować <canvas>, na którym narysuję scenę. Musi to być kontekst renderowania WebGLRenderingContext lub WebGL2RenderingContext zgodny z XR.
Wszystkie rysunki są tworzone za pomocą tych interfejsów API lub platformy opartej na WebGL, takiej jak Three.js.
Teraz, gdy mam już miejsce do rysowania, potrzebuję źródła treści, z którego będę czerpać inspirację. W tym celu tworzę instancję XRWebGLLayer. Łączę go z elementem canvas, wywołując funkcję XRSession.updateRenderState().
Gdy jestem w sesji, muszę mieć możliwość określenia, gdzie znajdują się poszczególne elementy w wirtualnej rzeczywistości. Będę potrzebować przestrzeni odniesienia. 'local-floor' Przestrzeń odniesienia to taka, w której punkt początkowy znajduje się w pobliżu widza, a oś Y ma wartość 0 na poziomie podłogi i nie powinna się przesuwać. Istnieją inne rodzaje przestrzeni odniesienia, ale to bardziej skomplikowany temat, niż mogę tu omówić. Przestrzeń odniesienia zapisuję w zmiennej, ponieważ będzie mi potrzebna podczas rysowania 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 prezentowania treści wirtualnych, które odbywa się w pętli klatek.
Uruchamianie pętli klatek
Pętla klatek to kontrolowana przez klienta nieskończona pętla, w której treść jest wielokrotnie rysowana na ekranie. Treści są rysowane w oddzielnych blokach zwanych klatkami. Kolejne klatki tworzą 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 klatek wygląda tak:
- Zadzwoń do firmy
XRSession.requestAnimationFrame(). W odpowiedzi klient użytkownika wywołuje funkcjęXRFrameRequestCallbackzdefiniowaną przez Ciebie. - W funkcji wywołania zwrotnego:
- Zadzwoń ponownie pod numer
XRSession.requestAnimationFrame(). - Uzyskiwanie pozycji widza.
- Przenieś (powiąż) kartę
WebGLFramebufferzXRWebGLLayernaWebGLRenderingContext. - Iteruj po każdym obiekcie
XRView, pobierając jegoXRViewportzXRWebGLLayeri przekazując go doWebGLRenderingContext. - Narysuj coś w buforze ramki.
- Zadzwoń ponownie pod numer
W pozostałej części tego artykułu opisujemy krok 1 i część kroku 2, czyli konfigurowanie i wywoływanie funkcji XRFrameRequestCallback. Pozostałe elementy kroku 2 są omówione w części II.
The XRFrameRequestCallback
Wartość XRFrameRequestCallback jest określana przez Ciebie. Przyjmuje 2 parametry: DOMHighResTimeStamp i instancję XRFrame. Obiekt XRFrame zawiera informacje potrzebne do wyrenderowania pojedynczej klatki na wyświetlaczu. Argument
DOMHighResTimeStamp jest przeznaczony do użycia w przyszłości.
Zanim cokolwiek zrobię, poproszę o następną klatkę animacji. Jak wspomnieliśmy wcześniej, czas wyświetlania klatek jest określany przez klienta użytkownika na podstawie sprzętu. Najpierw wysyłamy prośbę o następną klatkę, aby pętla klatek była 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 należy narysować coś dla widza. To temat na część II. Zanim to zrobimy, pokażę Ci, jak zakończyć sesję.
Zakończ sesję
Sesja immersyjna może się zakończyć z kilku powodów, m.in. z powodu zakończenia przez Twój kod za pomocą wywołania funkcji XRSession.end(). Inne przyczyny to odłączenie zestawu słuchawkowego lub przejęcie nad nim kontroli przez inną aplikację. Dlatego dobrze działająca aplikacja powinna monitorować zdarzenie end. W takim przypadku odrzuć sesję i powiązane z nią obiekty renderowania. Zakończonej sesji immersyjnej nie można wznowić. Aby ponownie wejść w tryb immersyjny, aplikacja musi rozpocząć nową sesję.
Przypomnij sobie z sekcji Wchodzenie do sesji, że podczas konfiguracji dodałem
onend procedurę obsługi zdarzeń.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
// More setup…
}
W module obsługi zdarzeń przywróć stan aplikacji sprzed rozpoczęcia sesji przez użytkownika.
function onSessionEnded(event) {
xrSession = null;
xrButton.textContent = 'Enter VR';
}
Podsumowanie
Nie wyjaśniłem wszystkiego, co jest potrzebne do napisania aplikacji Web XR lub AR. Mam nadzieję, że dałem Ci wystarczająco dużo informacji, abyś mógł samodzielnie zrozumieć kod i zacząć eksperymentować. W następnym artykule wyjaśnię pętlę klatek, w której treści są rysowane na ekranie.