Wirtualny internet to wirtualne światy hostowane w przeglądarce. Cała rzeczywistość wirtualna jest wyświetlana w przeglądarce lub w goglach do VR.
Wciągający internet to wirtualne światy hostowane w przeglądarce. Dotyczy to wszystkich treści w rzeczywistości wirtualnej (VR) wyświetlanych w przeglądarce lub w goglach VR, takich jak Daydream od Google, Oculus Rift, Samsung Gear VR, HTC Vive i gogle Windows Mixed Reality, a także treści w rzeczywistości rozszerzonej opracowanych na urządzenia mobilne z obsługą AR.
Chociaż do opisania wciągających doświadczeń używamy 2 określeń, należy je rozpatrywać jako spektrum od pełnej rzeczywistości do w pełni wciągającej rzeczywistości wirtualnej, z różnymi poziomami rzeczywistości rozszerzonej pośrodku.
Przykłady wciągających doświadczeń:
- filmy w technologii 360°,
- tradycyjne filmy 2D (lub 3D) prezentowane w realistycznym otoczeniu;
- Wizualizacje danych
- Zakupy do domu
- Sztuka
- Coś fajnego, o czym nikt jeszcze nie pomyślał
Jak się tam dostać?
Wirtualna sieć jest dostępna od prawie roku w postaci embrionalnej. Udało się to dzięki interfejsowi WebVR 1.1 API, który od wersji 62 Chrome jest dostępny w ramach testowania origin. Interfejs API jest też obsługiwany przez przeglądarki Firefox i Edge, a także przez polyfilla w Safari.
Czas przejść dalej.
Testowanie origin zakończyło się 24 lipca 2018 r., a specyfikacja została zastąpiona interfejsem WebXR Device API i nowym testem origin.
Co się stało z WebVR 1.1?
Wiele nauczyliśmy się na podstawie WebVR 1.1, ale z czasem stało się jasne, że potrzebne są poważne zmiany, aby obsługiwać typy aplikacji, które chcą tworzyć deweloperzy. Pełna lista wniosków jest zbyt długa, aby ją tu przytaczać, ale obejmuje ona takie problemy, jak: – wyraźne powiązanie interfejsu API z głównym wątkiem JavaScriptu, – zbyt wiele możliwości konfiguracji przez programistów, które prowadzą do błędnych konfiguracji, – częste przypadki, w których magiczne okno jest efektem ubocznym, a nie zamierzoną funkcją. (Magiczne okno to technika umożliwiająca wyświetlanie treści w trybie panoramicznym bez użycia zestawu słuchawkowego. Aplikacja renderuje jeden widok na podstawie czujnika orientacji urządzenia).
Nowy układ ułatwia wdrażanie i znacznie poprawia skuteczność. W tym samym czasie pojawiły się nowe przypadki użycia, takie jak rzeczywistość rozszerzona, i stało się ważne, aby interfejs API można było rozszerzyć, aby obsługiwał je w przyszłości.
Interfejs WebXR Device API został zaprojektowany i nazwany z myślą o tych rozszerzonych przypadkach użycia oraz zapewnia lepsze możliwości rozwoju. Implementatorzy WebVR zobowiązali się do przeniesienia się na interfejs WebXR Device API.
Czym jest interfejs WebXR Device API?
Podobnie jak specyfikacja WebVR, interfejs WebXR Device API jest produktem grupy społecznościowej Immersive Web, w której skład wchodzą m.in. Google, Microsoft i Mozilla. „X” w XR oznacza pewien rodzaj zmiennej algebraicznej, która może oznaczać dowolne z doświadczeń w zakresie rzeczywistości rozszerzonej. Jest ona dostępna w wymienionej wcześniej wersji próbnej origin, a także za pomocą polyfill.
Gdy ten artykuł został pierwotnie opublikowany w okresie testów beta przeglądarki Chrome 67, włączone były tylko funkcje VR. Rzeczywistość rozszerzona pojawiła się w Chrome 69. Więcej informacji na ten temat znajdziesz w artykule Rzeczywistość rozszerzona na potrzeby internetu.
Ten nowy interfejs API jest bardziej rozbudowany niż można to opisać w takim artykule. Chcę Ci przekazać wystarczającą ilość informacji, abyś mógł zacząć analizować próbki WebXR. Więcej informacji znajdziesz w oryginalenym tekście informującym oraz w przewodniku dla użytkowników wczesnej wersji przeglądarki Immersive Web. W miarę trwania testu wersji źródłowej będę rozszerzać tę ostatnią. Możesz zgłaszać problemy lub przesyłać prośby o przejęcie kodu.
W tym artykule omówię uruchamianie, zatrzymywanie i wykonywanie sesji XR oraz kilka podstawowych informacji o przetwarzaniu danych wejściowych.
Nie będę omawiać rysowania treści AR/VR na ekranie. Interfejs WebXR Device API nie udostępnia funkcji renderowania obrazu. Ty decydujesz. Rysowanie odbywa się za pomocą interfejsów WebGL API. Możesz to zrobić, jeśli masz ambitne plany. Zalecamy jednak użycie frameworka. Przykłady obrazu w głowie wykorzystują jedną z witryn stworzonych specjalnie na potrzeby demonstracji o nazwie Cottontail. Three.js obsługuje WebXR od maja. Nie słyszałem nic o A-Frame.
Uruchamianie i uruchamianie aplikacji
Oto podstawowy proces:
- Poproś o urządzenie XR.
- Jeśli jest to możliwe, poproś o sesję XR. Jeśli chcesz, aby użytkownik podłączył telefon do zestawu słuchawkowego, jest to sesja w trybie pełnoekranowym, do której można wejść za pomocą gestu.
- Użyj sesji do uruchomienia pętli renderowania, która zapewnia 60 ramek obrazu na sekundę. W każdym ujęciu wyświetlaj na ekranie odpowiednie treści.
- Wykonywanie pętli renderowania do momentu, gdy użytkownik zdecyduje się zamknąć aplikację.
- Zakończ sesję XR.
Przyjrzyjmy się temu zagadnieniu nieco dokładniej i zaprezentujmy kod. Nie będziesz mieć możliwości uruchomienia aplikacji, którą zaraz Ci pokażę. To tylko przykład.
Prośba o urządzenie XR
Tutaj zobaczysz standardowy kod wykrywania funkcji. Możesz to owinąć w funkcję o nazwie takiej jak checkForXR()
.
Jeśli nie korzystasz z sesji w trybie pełnoekranowym, możesz pominąć reklamowanie funkcji i uzyskiwanie gestów użytkownika, a następnie przejść bezpośrednio do żądania sesji. Sesja w pełni angażująca użytkownika to taka, która wymaga założenia słuchawek. W sesji niepełnej treści wyświetlają się tylko na ekranie urządzenia. Pierwsza z nich to to, o czym myśli większość osób, gdy mówi się o rzeczywistości wirtualnej lub rozszerzonej. Ten ostatni jest czasami nazywany „magicznym oknem”.
if (navigator.xr) {
navigator.xr.requestDevice()
.then(xrDevice => {
// Advertise the AR/VR functionality to get a user gesture.
})
.catch(err => {
if (err.name === 'NotFoundError') {
// No XRDevices available.
console.error('No XR devices available:', err);
} else {
// An error occurred while requesting an XRDevice.
console.error('Requesting XR device failed:', err);
}
})
} else{
console.log("This browser does not support the WebXR API.");
}
Prośba o sesję XR
Mamy już urządzenie i gesty użytkownika, więc czas na sesję. Aby utworzyć sesję, przeglądarka potrzebuje płótna, na którym będzie można rysować.
xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions = {
// The immersive option is optional for non-immersive sessions; the value
// defaults to false.
immersive: false,
outputContext: xrPresentationContext
}
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
// Use a WebGL context as a base layer.
xrSession.baseLayer = new XRWebGLLayer(session, gl);
// Start the render loop
})
Uruchamianie pętli renderowania
Kod potrzebny do wykonania tego kroku wymaga trochę pracy. Aby to wyjaśnić, powiem Ci kilka słów. Jeśli chcesz zobaczyć kod końcowy, przejdź do niego, aby go szybko przejrzeć, a potem wróć do tego artykułu, aby przeczytać pełne wyjaśnienie. Jest wiele rzeczy, których nie da się wywnioskować.
Podstawowy proces pętli renderowania:
- Żądanie ramki animacji
- Zapytanie o położenie urządzenia.
- Rysowanie treści w zależności od położenia urządzenia.
- wykonać niezbędne czynności dotyczące urządzeń wejściowych.
- Powtarzaj 60 razy na sekundę, aż użytkownik zdecyduje się zakończyć.
Żądanie ramki prezentacji
Słowo „ramka” ma w kontekście WebXR kilka znaczeń. Pierwszym jest układ odniesienia, który określa, na podstawie czego oblicza się początek układu współrzędnych i co się z nim dzieje, gdy urządzenie się porusza. (Czy widok pozostaje taki sam, gdy użytkownik się porusza, czy zmienia się tak jak w rzeczywistości?)
Drugi typ ramki to ramka prezentacji, reprezentowana przez obiekt XRFrame
. Ten obiekt zawiera informacje potrzebne do renderowania pojedynczego obrazu sceny AR/VR na urządzeniu. Może to być nieco mylące, ponieważ ramka prezentacji jest pobierana przez wywołanie requestAnimationFrame()
.
Dzięki temu jest ona zgodna z window.requestAnimationFrame()
.
Zanim podam Ci więcej informacji, pokażę Ci kod. Przykład poniżej pokazuje, jak pętla renderowania jest uruchamiana i utrzymywana. Zwróć uwagę na podwójne zastosowanie ramki Zwróć uwagę na rekurencyjne wywołanie funkcji requestAnimationFrame()
. Ta funkcja będzie wywoływana 60 razy na sekundę.
xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
// The time argument is for future use and not implemented at this time.
// Process the frame.
xrFrame.session.requestAnimationFrame(onFrame);
}
});
Pozycje
Zanim zaczniesz cokolwiek rysować na ekranie, musisz wiedzieć, w jaką stronę skierowany jest wyświetlacz urządzenia i musisz mieć dostęp do ekranu. Ogólnie pozycja i orientacja obiektu w AR/VR nazywana jest pozą. Zarówno widzowie, jak i urządzenia wejściowe mają pozę. (omówię je później). Zarówno pozy widza, jak i urządzenia wejściowego są zdefiniowane jako macierz 4 × 4 przechowywana w kolumnie Float32Array
w kolejności głównej. Aby uzyskać pozę widza, wywołaj funkcję XRFrame.getDevicePose()
w bieżącym obiekcie ramki animacji.
Zawsze sprawdzaj, czy otrzymasz odpowiedź. Jeśli coś pójdzie nie tak, nie chcesz rysować na ekranie.
let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
// Draw something to the screen.
}
Wyświetlenia
Po sprawdzeniu pozy czas na narysowanie czegoś. Obiekt, do którego rysujesz, nazywa się widokiem (XRView
). Właśnie w tym miejscu staje się istotny typ sesji. Wyświetlenia są pobierane z obiektu XRFrame
jako tablica. Jeśli jesteś w sesji nie-imersyjnej, tablica ma jeden widok. Jeśli korzystasz z sesji w trybie immersyjnym, tablica będzie miała 2 elementy – po jednym dla każdego oka.
for (let view of xrFrame.views) {
// Draw something to the screen.
}
Jest to ważna różnica między WebXR a innymi systemami immersyjnymi. Chociaż może się wydawać, że iterowanie w jednym widoku jest bezcelowe, pozwala to mieć jedną ścieżkę renderowania dla różnych urządzeń.
Cały cykl renderowania
Po połączeniu tych wszystkich elementów otrzymuję kod widoczny poniżej. W przypadku urządzeń wejściowych pozostawiłem miejsce na placeholder, o którym opowiem w późniejszej sekcji.
xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
// The time argument is for future use and not implemented at this time.
let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
for (let view of xrFrame.views) {
// Draw something to the screen.
}
}
// Input device code will go here.
frame.session.requestAnimationFrame(onFrame);
}
}
Zakończ sesję XR
Sesja XR może się zakończyć z różnych powodów, m.in. przez wywołanie funkcji XRSession.end()
w Twoim kodzie. Inne przyczyny to odłączenie zestawu słuchawkowego lub przejęcie nad nim kontroli przez inną aplikację. Dlatego aplikacja o poprawnych zachowaniach powinna monitorować zdarzenie zakończenia i po jego wystąpieniu odrzucać obiekty sesji i renderowania. Zakończonej sesji XR nie można wznowić.
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
// Create a WebGL layer and initialize the render loop.
xrSession.addEventListener('end', onSessionEnd);
});
// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
xrSession = null;
// Ending the session stops executing callbacks passed to the XRSession's
// requestAnimationFrame(). To continue rendering, use the window's
// requestAnimationFrame() function.
window.requestAnimationFrame(onDrawFrame);
}
Jak działa interakcja?
Podobnie jak w przypadku czasu trwania aplikacji, pokażę Ci tylko, jak można wchodzić w interakcje z obiektami w rzeczywistości rozszerzonej lub wirtualnej.
Interfejs WebXR Device API stosuje podejście „wskaż i kliknij” do danych wejściowych użytkownika. W ramach tego podejścia każde źródło danych ma zdefiniowany promień wskaźnika, który wskazuje, na co wskazuje urządzenie wejściowe, oraz zdarzenia wskazujące, kiedy coś zostało wybrane.
Aplikacja rysuje promień wskaźnika i wskazuje, na co jest skierowany. Gdy użytkownik kliknie urządzenie wejściowe, zostaną wywołane zdarzenia select
, selectStart
i selectEnd
. Aplikacja określa, co zostało kliknięte, i odpowiednio reaguje.
Urządzenie wejściowe i promiennik
Dla użytkowników promienie kursora to tylko słaba linia między kontrolerem a tym, na co użytkownik wskazuje. Aplikacja musi ją jednak narysować. Oznacza to, że musisz określić pozycję urządzenia wejściowego i narysować linię od jego lokalizacji do obiektu w przestrzeni AR/VR. Proces ten wygląda mniej więcej tak:
let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
let inputPose = frame.getInputPose(inputSource, xrFrameOfRef);
if (!inputPose) {
continue;
}
if (inputPose.gripMatrix) {
// Render a virtual version of the input device
// at the correct position and orientation.
}
if (inputPose.pointerMatrix) {
// Draw a ray from the gripMatrix to the pointerMatrix.
}
}
Jest to uproszczona wersja próbki kodu śledzącego dane wejściowe z grupy społeczności Immersive Web. Podobnie jak w przypadku renderowania klatek, rysowanie promienia wskaźnika i urządzenia zależy od Ciebie. Jak już wspomnieliśmy, ten kod musi być wykonywany w ramach pętli renderowania.
Wybieranie elementów w wirtualnym środowisku
Wskazywanie rzeczy w AR/VR jest dość bezużyteczne. Aby robić coś pożytecznego, użytkownicy muszą mieć możliwość wybierania elementów. Interfejs WebXR Device API udostępnia 3 zdarzenia, które pozwalają reagować na interakcje użytkownika: select
, selectStart
i selectEnd
. Jest to nieoczekiwana osobliwość: aplikacja informuje tylko, że kliknięto urządzenie wejściowe. Nie wskazują, który element w otoczeniu został kliknięty. Obsługa zdarzeń jest dodawana do obiektu XRSession
i powinna być dodana, gdy tylko będzie dostępna.
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
// Create a WebGL layer and initialize the render loop.
xrSession.addEventListener('selectstart', onSelectStart);
xrSession.addEventListener('selectend', onSelectEnd);
xrSession.addEventListener('select', onSelect);
});
Ten kod jest oparty na przykładzie funkcji Input Selection, jeśli chcesz uzyskać więcej informacji.
Aby dowiedzieć się, co zostało kliknięte, użyj pozy. (Zaskoczony? Nie sądzę.) Szczegóły są specyficzne dla Twojej aplikacji lub używanego przez Ciebie frameworku i poza zakresem tego artykułu. Metoda Cottontail jest opisana w sekcji dotyczącej wyboru danych wejściowych.
function onSelect(ev) {
let inputPose = ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
if (!inputPose) {
return;
}
if (inputPose.pointerMatrix) {
// Figure out what was clicked and respond.
}
}
Podsumowanie: plany na przyszłość
Jak już wspomniałem, rzeczywistość rozszerzona ma zostać udostępniona w Chrome 69 (w wersji Canary w czerwcu 2018 r.). Zachęcam jednak do wypróbowania tego, co mamy do tej pory. Potrzebujemy Twojej opinii, aby ulepszyć tę funkcję. Aby śledzić postępy, odwiedź stronę ChromeStatus.com i sprawdź WebXR HitTest. Możesz też śledzić ankiety WebXR, co poprawi śledzenie postawy.