Rzeczywistość wirtualna w internecie

Kilka podstawowych informacji, dzięki którym przygotujesz się na szerokie spektrum wrażeń: rzeczywistość wirtualna, rzeczywistość rozszerzona i inne.

Joe Medley
Joe Medley

Immersyjność pojawiła się w internecie w Chrome 79. WebXR Device API zapewnia rzeczywistość wirtualną wzbogaconą o rzeczywistość wirtualną, a Chrome 81 – obsługę tej rzeczywistości. Z kolei aktualizacja interfejsu GamePad API poszerza zakres zaawansowanych funkcji o elementy sterujące o rzeczywistość wirtualną. Te specyfikacje będą wkrótce obsługiwać inne przeglądarki, w tym Firefox Reality, Oculus Browser, Edge i Magic Leap Helio.

Ten artykuł rozpoczyna serię na temat rzeczywistości wirtualnej. Ta rata obejmuje konfigurowanie podstawowej aplikacji WebXR, a także rozpoczynanie i kończenie sesji XR. Późniejsze artykuły będą dotyczyć pętli ramek (konia roboczego środowiska WebXR), specyfiki rzeczywistości rozszerzonej oraz interfejsu WebXR Hit Test API, który umożliwia wykrywanie powierzchni w ramach sesji AR. O ile nie wskazano inaczej, wszystko, co tu omówię i kolejne artykuły, odnosi się w równym stopniu do AR i VR.

Czym jest immersyjny internet?

Doznania wciągające – rzeczywistość rozszerzona i wirtualna – są nazywane 2 terminami. Wielu myśli o nich w spektrum od pełnej rzeczywistości po całkowicie wirtualne. „X” w XR ma odzwierciedlać to myślenie w postaci zmiennej algebraicznej, która reprezentuje wszystko w spektrum doświadczeń immersyjnych.

Wykres ilustrujący spektrum wrażeń wizualnych – od pełnej rzeczywistości do całkowicie realistycznej.
Spektrum wrażeń immersyjnych

Przykłady doświadczeń immersyjnych to:

  • Gry
  • Filmy 360°
  • tradycyjne filmy 2D (lub 3D) prezentowane w rzeczywistym otoczeniu;
  • Zakup domu
  • Wyświetlanie produktów w domu przed ich zakupem
  • Interaktywna sztuka
  • Czego jeszcze nikt nie pomyślał

Pojęcia i zastosowanie

omówię kilka podstaw korzystania z interfejsu WebXR Device API. Jeśli potrzebujesz bardziej szczegółowych informacji, zapoznaj się z przykładami WebXR przygotowanymi przez Immersive Web wykonującą pracę z grupy Immersive Web znajdującą się na tej stronie lub z coraz większymi materiałami referencyjnymi w MDN. Jeśli znasz wczesne wersje interfejsu WebXR Device API, przejrzyj cały ten materiał. Nastąpiło zmiany.

Kod w tym artykule jest oparty na przykładowej aplikacji barebones z grupy Immersive Web Roboczo (prezentacja, źródło), ale został zmodyfikowany, aby był bardziej przejrzysty i łatwy w obsłudze.

Częścią tworzenia specyfikacji WebXR było doprecyzowanie zabezpieczeń i środków ochrony prywatności w celu ochrony użytkowników. Dlatego wdrożenia muszą spełniać określone wymagania. Strona internetowa lub aplikacja musi być aktywna i aktywna, zanim będzie mogła prosić użytkownika o jakiekolwiek poufne treści. Strony internetowe i aplikacje muszą być wyświetlane przez HTTPS. Sam interfejs API chroni informacje uzyskane z czujników i aparatów, których potrzebuje do działania.

Poproś o sesję

Rozpoczęcie sesji XR wymaga gestu użytkownika. Aby to uzyskać, użyj wykrywania funkcji do przetestowania XRSystem (za pomocą navigator.xr) i zadzwoń pod numer XRSystem.isSessionSupported(). Pamiętaj, że w Chrome 79 i 80 obiekt XRSystem nazywał się XR.

W poniższym przykładzie wskażę, że chcę korzystać z sesji rzeczywistości wirtualnej 'immersive-vr' o typie sesji. Pozostałe typy sesji to 'immersive-ar' i 'inline'. Sesja wbudowana służy do prezentowania treści w kodzie HTML i służy głównie do zwiastunów. Widać to w przykładzie 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 pozwala mi wykonać 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 następnie wysyłam żądanie sesji.

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 instancji navigator do xr do instancji XRSession. We wczesnych wersjach interfejsu API skrypt musiał zażądać urządzenia przed żądaniem sesji. Teraz urządzenie jest przejmowane domyślnie.

Wpisz sesję

Po otrzymaniu sesji muszę ją uruchomić i do niej dołączyć. Ale najpierw muszę skonfigurować kilka rzeczy. Sesja wymaga modułu obsługi zdarzeń onend, aby można było zresetować aplikację lub stronę internetową po jej zamknięciu.

Potrzebuję też elementu <canvas>, żeby narysować scenę. Musi być zgodny z XR WebGLRenderingContext lub WebGL2RenderingContext. Rysowanie odbywa się przy użyciu tych narzędzi lub platformy opartej na WebGL, takiej jak Three.js.

Gdy mam już miejsce do rysowania, potrzebuję źródła treści, którym to rysuję. Tworzę do niego instancję XRWebGLLayer. Powiąż go z obrazem, wywołując XRSession.updateRenderState().

Gdy prowadzę sesję, muszę mieć możliwość określenia miejsc w rzeczywistości wirtualnej. Potrzebuję miejsca referencyjnego. Przestrzeń referencyjna 'local-floor' to obszar, w którym punkt początkowy znajduje się w pobliżu przeglądarki, a oś Y na poziomie piętra ma wartość 0 i nie powinna się poruszać. Istnieją inne typy obszarów referencyjnych, ale to bardziej złożony temat, niż możemy tu przedstawić. Zapisuję przestrzeń referencyjną w zmiennej, ponieważ będzie ona potrzebna przy rysowaniu 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 referencyjnej dzwonię XRSession.requestAnimationFrame(). To początek prezentacji treści wirtualnych, która odbywa się w pętli klatki.

Uruchom pętlę ramek

Jest to nieskończona pętla kontrolowana przez klienta użytkownika, w której treść jest wielokrotnie wyświetlana na ekranie. Zawartość jest rysowana w odrębnych blokach zwanych ramkami. Kolejne kadry stwarzają iluzję ruchu. W aplikacjach VR liczba klatek na sekundę może wynosić od 60 do 144. AR na Androida działa z szybkością 30 klatek na sekundę. Kod nie powinien zakładać żadnej konkretnej liczby klatek.

Podstawowy proces pętli ramki wygląda tak:

  1. Zadzwoń do firmy XRSession.requestAnimationFrame(). W odpowiedzi klient użytkownika wywołuje zdefiniowane przez Ciebie polecenie XRFrameRequestCallback.
  2. Funkcja wywołania zwrotnego:
    1. Zadzwoń jeszcze raz do: XRSession.requestAnimationFrame().
    2. Przyjęcie pozycji widza.
    3. Przekaż („bind”) metodę WebGLFramebuffer z: XRWebGLLayer do: WebGLRenderingContext.
    4. Wykonaj iterację nad każdym obiektem XRView, pobierając jego wartość XRViewport z XRWebGLLayer i przekazując do WebGLRenderingContext.
    5. Narysuj coś do bufora ramki.

W pozostałej części tego artykułu opisano krok 1 oraz część kroku 2, czyli konfigurowanie i wywoływanie XRFrameRequestCallback. Pozostałe elementy kroku 2 omawiamy w części II.

Wywołanie zwrotne żądania XRFrameRequest

XRFrameRequestCallback jest określany przez Ciebie. Przyjmuje on 2 parametry: instancję DOMHighResTimeStamp i XRFrame. Obiekt XRFrame dostarcza informacje potrzebne do wyrenderowania pojedynczej klatki na wyświetlaczu. Argument DOMHighResTimeStamp jest przeznaczony do użycia w przyszłości.

Zanim cokolwiek zrobię, poproszę Cię o utworzenie następnej klatki animacji. Jak już wspomnieliśmy, czas wyświetlania klatek jest określany przez klienta użytkownika na podstawie używanego sprzętu. Żądanie pierwszej ramki powoduje, że pętla jest kontynuowana, nawet jeśli podczas wywołania zwrotnego coś w trakcie wywołania zwrotnego spowoduje błąd.

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  // Render a frame.
}

W tym momencie nadszedł czas, żeby coś narysować dla widza. To temat do części II. Zanim się tam przejdę, pokażę Ci, jak zakończyć sesję.

Zakończ sesję

Sesja wciągająca może zakończyć się z kilku powodów, m.in. przez wywołanie Twojego kodu przez wywołanie XRSession.end(). Inne przyczyny to odłączenie zestawu lub inna aplikacja przejmująca nad nim kontrolę. Dlatego w dobrej aplikacji powinna być monitorowana zdarzenie end. W takim przypadku odrzuć sesję i powiązane z nią obiekty renderowania. Zakończonej sesji immersyjnej nie można wznowić. Aby można było wrócić do trybu immersyjnego, moja aplikacja musi rozpocząć nową sesję.

Od strony Rozpoczynanie sesji przypominam, że podczas konfiguracji dodałem moduł obsługi zdarzeń onend.

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);
  // More setup…
}

W module obsługi zdarzeń przywróć stan aplikacji przed rozpoczęciem sesji użytkownika.

function onSessionEnded(event) {
  xrSession = null;
  xrButton.textContent = 'Enter VR';
}

Podsumowanie

Nie wyjaśniłem wszystkiego, czego potrzebujesz, by napisać aplikację Web XR lub AR. Mam nadzieję, że udało mi się już samemu znaleźć kod, aby mógł rozumieć kod, i zacząć eksperymentować. W następnym artykule omówię pętlę, w której treści są wyświetlane na ekranie.

Autor zdjęcia: JESHOOTS.COM na stronie Unsplash