Jeśli korzystasz już z interfejsu WebXR Device API, jesteś już prawie na ukończeniu.
Interfejs WebXR Device API został wprowadzony jesienią ubiegłego roku w Chrome 79. Jak już wspomnieliśmy, prace nad implementacją interfejsu API w Chrome są w toku. Z przyjemnością informujemy, że część prac została już ukończona. W Chrome 81 pojawiły się 2 nowe funkcje:
Ten artykuł dotyczy rzeczywistości rozszerzonej. Jeśli korzystasz już z interfejsu API WebXR Device, ucieszy Cię wiadomość, że nie ma zbyt wiele nowych rzeczy do nauczenia się. Wchodzenie do sesji WebXR przebiega w dużej mierze tak samo. Uruchomienie pętli ramek przebiega w podobny sposób. Różnice polegają na konfiguracjach, które umożliwiają wyświetlanie treści w odpowiednich warunkach dla rzeczywistości rozszerzonej. Jeśli nie znasz podstawowych pojęć związanych z WebXR, przeczytaj moje wcześniejsze wpisy na temat interfejsu WebXR Device API lub przynajmniej zapoznaj się z omawianymi w nich tematami. Musisz wiedzieć, jak poprosić o sesję i wejść do niej oraz jak uruchomić pętlę ramek.
Informacje o testowaniu trafień znajdziesz w artykule Umieszczanie obiektów wirtualnych w rzeczywistych widokach. Kod w tym artykule jest oparty na przykładowej sesji wciągającej rzeczywistości rozszerzonej (demo source) z interfejsu WebXR Device API grupy roboczej Immersive Web Working Group.
Zanim zaczniesz edytować kod, przynajmniej raz skorzystaj z przykładu sesji z rozszerzoną rzeczywistością. Potrzebujesz nowoczesnego telefonu z Androidem i przeglądarką Chrome 81 lub nowszą.
Do czego się przydaje?
Rzeczywistość rozszerzona będzie cennym dodatkiem do wielu istniejących i nowych stron internetowych, ponieważ pozwoli na implementację przypadków użycia AR bez potrzeby opuszczania przeglądarki. Może ona na przykład pomóc użytkownikom w nauce w witrynach edukacyjnych i umożliwić potencjalnym kupującym wizualizację produktów w ich domach.
Rozważ drugi przypadek użycia. Wyobraź sobie symulację umieszczenia w rzeczywistej scenie wirtualnego obiektu w naturalnej wielkości. Po umieszczeniu obraz pozostaje na wybranej powierzchni, ma rozmiary odpowiadające rzeczywistemu obiektowi na tej powierzchni i pozwala użytkownikowi poruszać się wokół niego oraz zbliżać się do niego lub oddalać. Dzięki temu widzowie mogą lepiej poznać obiekt niż w przypadku obrazu dwuwymiarowego.
Zbywam trochę wprzód. Aby to zrobić, potrzebujesz funkcji AR i środka wykrywania powierzchni. W tym artykule omawiamy tę pierwszą opcję. W powiązanym wyżej artykule o interfejsie WebXR Hit Test API znajdziesz więcej informacji na ten temat.
Prośba o sesję
Prośba o sesję jest bardzo podobna do tego, co już znasz. Najpierw sprawdź, czy wybrany typ sesji jest dostępny na bieżącym urządzeniu, wykonując wywołanie xr.isSessionSupported()
. Zamiast 'immersive-vr'
, jak poprzednio, poproś o 'immersive-ar'
.
if (navigator.xr) {
const supported = await navigator.xr.isSessionSupported('immersive-ar');
if (supported) {
xrButton.addEventListener('click', onButtonClicked);
xrButton.textContent = 'Enter AR';
xrButton.enabled = supported; // supported is Boolean
}
}
W tym przypadku również pojawi się przycisk „Wejdź do AR”. Gdy użytkownik kliknie ten przycisk, wywołaj funkcję xr.requestSession()
, przekazując jej argument 'immersive-ar'
.
let xrSession = null;
function onButtonClicked() {
if (!xrSession) {
navigator.xr.requestSession('immersive-ar')
.then((session) => {
xrSession = session;
xrSession.isImmersive = true;
xrButton.textContent = 'Exit AR';
onSessionStarted(xrSession);
});
} else {
xrSession.end();
}
}
Właściwość typu convenience
Zauważysz pewnie, że w ostatnim przykładzie kodu podświetlono 2 wiersze.
Wygląda na to, że obiekt XRSession
ma właściwość o nazwie isImmersive
. To jest własność, którą utworzyłem dla wygody. Nie jest ona częścią specyfikacji. Użyję jej później, aby podjąć decyzję, co wyświetlić widzowi. Dlaczego ta usługa nie jest częścią interfejsu API? Ponieważ aplikacja może potrzebować śledzenia tej właściwości w inny sposób, autorzy specyfikacji postanowili zachować interfejs API w czystej formie.
Rozpoczynanie sesji
Przypomnij sobie, jak wyglądała onSessionStarted()
w moim poprzednim artykule:
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
let canvas = document.createElement('canvas');
gl = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
xrSession.requestReferenceSpace('local-floor')
.then((refSpace) => {
xrRefSpace = refSpace;
xrSession.requestAnimationFrame(onXRFrame);
});
}
Muszę dodać kilka rzeczy, aby uwzględnić renderowanie rzeczywistości rozszerzonej. Wyłącz tło. Najpierw określę, czy potrzebuję tła. Właśnie w tym miejscu po raz pierwszy użyję obiektu typu convenience.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
if (session.isImmersive) {
removeBackground();
}
let canvas = document.createElement('canvas');
gl = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
xrSession.requestAnimationFrame(onXRFrame);
});
}
Przestrzenie referencyjne
W moich wcześniejszych artykułach tylko pobieżnie omawiałem przestrzenie referencyjne. Przykład, który opisuję, używa dwóch z nich, więc nadszedł czas, aby to uzupełnić.
Przestrzeń odniesienia opisuje związek między światem wirtualnym a środowiskiem fizycznym użytkownika. Dotyczy to:
- Określanie punktu wyjścia dla układu współrzędnych używanego do wyrażania pozycji w świecie wirtualnym.
- Określa, czy użytkownik ma się poruszać w ramach tego układu współrzędnych.
- Czy system współrzędnych ma wstępnie określone granice. (przykłady pokazane tutaj nie korzystają z uprzednio ustalonych granic układów współrzędnych).
W przypadku wszystkich przestrzeni odniesienia współrzędna X oznacza lewo i prawo, współrzędna Y – w górę i w dół, a współrzędna Z – do przodu i do tyłu. Wartości dodatnie odpowiadają odpowiednio prawej stronie, górze i tyłowi.
Współrzędne zwracane przez funkcję XRFrame.getViewerPose()
zależą od żądanego typu przestrzeni odniesienia.
Więcej informacji na ten temat znajdziesz w sekcji dotyczącej pętli ramek. Teraz musimy wybrać typ odniesienia odpowiedni do rozszerzonej rzeczywistości. Ponownie używam właściwości skrótu.
let refSpaceType
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
if (session.isImmersive) {
removeBackground();
}
let canvas = document.createElement('canvas');
gl = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
xrSession.requestAnimationFrame(onXRFrame);
});
}
Jeśli otworzysz przykład sesji z rozszerzoną rzeczywistością, zauważysz, że początkowo scena jest statyczna i nie ma nic wspólnego z rozszerzoną rzeczywistością. Aby poruszać się po scenie, przeciągnij palcem lub przesuń po niej. Jeśli klikniesz „ROZPOCZNIJ AR”, tło zniknie i będziesz mieć możliwość poruszania się po scenie, przenosząc urządzenie. Tryby te używają różnych typów przestrzeni odniesienia. Powyższy wyróżniony tekst pokazuje, jak to zrobić. Używa on tych typów odwołań:
local
– punkt początkowy znajduje się w miejscu, w którym znajdował się użytkownik w momencie utworzenia sesji. Oznacza to, że nie zawsze jest ono dobrze zdefiniowane, a dokładna pozycja punktu początkowego może się różnić w zależności od platformy. Chociaż nie ma z góry określonych granic przestrzeni, oczekuje się, że treści można oglądać bez ruchu, z wyjątkiem obracania. Jak widać na przykładzie naszej funkcji AR, możliwe jest pewne poruszanie się w przestrzeni.
viewer
– najczęściej używany w przypadku treści wyświetlanych w ramach strony. Ten układ jest dostosowywany do urządzenia wyświetlającego. Gdy zostanie przekazany do getViewerPose, nie zapewnia śledzenia i zawsze zwraca pozę w początku, chyba że aplikacja zmodyfikuje ją za pomocą XRReferenceSpace.getOffsetReferenceSpace()
. Przykład korzysta z tego mechanizmu, aby umożliwić przesuwanie kamery za pomocą dotyku.
Wykonywanie pętli ramkowej
Koncepcyjnie nic się nie zmienia w stosunku do tego, co zrobiłem podczas sesji VR opisanej w moim wcześniejszym artykule. Przekaż typ przestrzeni referencyjnej do XRFrame.getViewerPose()
.
Zwrócona wartość XRViewerPose
będzie odpowiadać bieżącemu typowi przestrzeni referencyjnej. Użycie opcji viewer
jako domyślnej pozwala na wyświetlanie podglądów treści przed uzyskaniem zgody użytkownika na korzystanie z AR lub VR. To pokazuje ważną kwestię: zawartość w ramce używa tej samej pętli ramki co treści w trybie pełnoekranowym, co zmniejsza ilość kodu, który należy utrzymywać.
function onXRFrame(hrTime, xrFrame) {
let xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
let xrViewerPose = xrFrame.getViewerPose(refSpaceType);
if (xrViewerPose) {
// Render based on the pose.
}
}
Podsumowanie
Ta seria artykułów obejmuje tylko podstawy wdrażania treści w internecie. Więcej możliwości i przypadków użycia znajdziesz w próbkach interfejsu WebXR Device API przygotowanych przez grupę roboczą ds. wirtualnej rzeczywistości w internecie. Opublikowaliśmy też artykuł o testach porównawczych, który wyjaśnia, jak działa interfejs API do wykrywania powierzchni i umieszczania wirtualnych obiektów w rzeczywistym widoku z kamery. Zapoznaj się z tymi artykułami i śledź bloga web.dev, aby w nadchodzącym roku czytać więcej artykułów.
Zdjęcie: David Grandmougin, Unsplash