Jeśli zdarzyło Ci się już korzystać z interfejsu WebXR Device API, prawdopodobnie udało Ci się go osiągnąć.
Interfejs WebXR Device API został wysłany jesienią zeszłego roku w Chrome 79. Jak już wspomnieliśmy, trwa wdrażanie tego interfejsu API w Chrome. Chrome z przyjemnością informuje, że niektóre prace zostały zakończone. W Chrome 81 pojawiły się 2 nowe funkcje:
Ten artykuł dotyczy rzeczywistości rozszerzonej. Jeśli już korzystałeś(-aś) z interfejsu WebXR Device API, ucieszy Cię informacja, że nie trzeba jeszcze uczyć się obsługi. Rozpoczęcie sesji WebXR w dużym stopniu odbywa się tak samo. Zapętlanie ramki przebiega w zasadzie tak samo. Różnice wynikają z konfiguracji, które umożliwiają odpowiednie wyświetlanie treści w rzeczywistości rozszerzonej. Jeśli nie znasz podstawowych pojęć związanych z WebXR, przeczytaj moje wcześniejsze posty o interfejsie WebXR Device API lub przynajmniej zapoznaj się z poruszanymi w nim tematami. Potrafisz poprosić o sesję i dołączyć do niej oraz wiedzieć, jak uruchomić pętlę ramek.
Informacje o testowaniu trafień znajdziesz w artykule towarzyszącym Pozycjonowanie obiektów wirtualnych w widokach rzeczywistych. Kod w tym artykule jest oparty na przykładowej sesji Immersive AR Session (prezentacja źródło) z przykładów interfejsu WebXR Device API od Immersive Web Working Group.
Zanim zagłębimy się w kod, skorzystaj z przykładowej sesji Immersive AR co najmniej raz. Potrzebujesz nowoczesnego telefonu z Androidem i Chrome 81 lub nowszą wersją.
Do czego służy?
Rzeczywistość rozszerzona będzie cennym dodatkiem do wielu istniejących i nowych stron internetowych, ponieważ umożliwi implementowanie przypadków użycia AR bez opuszczania przeglądarki. Na przykład może pomóc użytkownikom w nauce w witrynach edukacyjnych i umożliwić potencjalnym nabywcom wizualizację przedmiotów w ich domu podczas zakupów.
Rozważmy drugi przypadek użycia. Wyobraź sobie, że symulujesz w rzeczywistej scenie rzeczywistą wielkość obiektu wirtualnego. Po umiejscowieniu obraz pozostaje na wybranej powierzchni i ma taki rozmiar, jaki miałby być, gdyby znajdował się na niej dany element. Umożliwia to użytkownikowi przesuwanie się wokół niej, a także bliższe jej obrócenie. Dzięki temu widzowie mogą lepiej zrozumieć dany obiekt, niż w przypadku obrazów dwuwymiarowych.
Wyprzedzam się trochę. Aby wykonać to, co opisałem, potrzebujesz funkcji AR i pewnych sposobów wykrywania platform. Artykuł dotyczy poprzedniego. W tym artykule znajdziesz informacje o tym drugim artykule na temat interfejsu WebXR Hit Test API (link do strony powyżej).
Wysyłanie prośby o sesję
Żądanie sesji jest bardzo podobne do tego, którego widziałeś(-aś) wcześniej. Najpierw sprawdź, czy wybrany typ sesji jest dostępny na bieżącym urządzeniu, dzwoniąc pod numer xr.isSessionSupported()
. Zamiast wysyłać żądanie 'immersive-vr'
, poproś o to '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
}
}
Tak jak poprzednio, włączenie tej opcji powoduje włączenie przycisku „Enter AR” (Wpisz AR). Gdy użytkownik go kliknie, wywołaj xr.requestSession()
, a także przekaże '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();
}
}
Nieruchomość udogodnień
W ostatnim przykładowym kodzie zostały wyróżnione 2 wiersze.
Wygląda na to, że obiekt XRSession
ma właściwość o nazwie isImmersive
. To udoskonalona przeze mnie właściwość, która nie jest częścią specyfikacji. Wykorzystam ją później do podjęcia decyzji o tym, co pokazać widzom. Dlaczego ta właściwość
nie jest częścią interfejsu API? Aplikacja może śledzić tę właściwość w inny sposób, więc autorzy specyfikacji zdecydowali się utrzymać porządek w interfejsie API.
Rozpoczęcie sesji
Przypomnij sobie, jak wyglądał tekst onSessionStarted()
we wcześniejszym 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 muszę określić, czy potrzebuję tła. Od tego miejsca będę korzystać z mojej usługi dogodnej.
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);
});
}
Obszary referencyjne
Moje wcześniejsze artykuły przeglądały miejsca referencyjne. W próbce, którą opisuję, wykorzystam 2 z nich, więc pora to poprawić.
Przestrzeń referencyjna opisuje relację między światem wirtualnym a środowiskiem fizycznym użytkownika. Jest to możliwe dzięki:
- Określanie punktu początkowego układu współrzędnych używanego do wyrażania pozycji w świecie wirtualnym.
- Określa, czy użytkownik ma poruszać się w obrębie tego układu współrzędnych.
- Określa, czy ten układ współrzędnych ma wcześniej ustalone granice. (Te przykłady nie dotyczą układów współrzędnych z ustalonymi wcześniej granicami).
We wszystkich przestrzeniach referencyjnych współrzędna X oznacza lewo i prawo, Y – w górę i w dół, a Z – do przodu i do tyłu. Wartości dodatnie to odpowiednio pionowo, w górę i w tył.
Współrzędne zwracane przez funkcję XRFrame.getViewerPose()
zależą od żądanego typu przestrzeni referencyjnej.
Więcej o tym dowiesz się, gdy dojdziemy do pętli klatek. Na razie musimy wybrać typ pliku referencyjnego
odpowiedni dla rzeczywistości rozszerzonej. Ponownie korzystamy
z mojej dogodnej usługi.
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);
});
}
Po przejściu do przykładowej sesji AR zauważysz, że początkowo scena jest nieruchoma, a rzeczywista rozszerzona w ogóle nie jest. Aby poruszać się po scenie, możesz przeciągać i przesuwać palcem. Po kliknięciu „ROZPOCZNIJ AR” tło zniknie i będzie można poruszać się po scenie, poruszając urządzeniem. Tryby korzystają z różnych typów przestrzeni referencyjnej. Zaznaczony tekst powyżej pokazuje, jak jest wybierany. Używa tych typów odwołań:
local
– źródło znajduje się w miejscu przeglądającego w momencie tworzenia sesji. Oznacza to, że doświadczenie nie musi mieć jasno określonej ceny, a dokładne położenie może się różnić w zależności od platformy. Choć nie ma wstępnie ustalonych granic, to treści można oglądać bez żadnych ruchów poza obracaniem. Jak widać na naszym przykładzie AR, można się poruszać w obrębie przestrzeni.
viewer
– najczęściej używane w przypadku treści prezentowanych w treści strony, w tym miejscu umiejscowionym po ekranie urządzenia. Przekazana do getViewerPose nie zapewnia śledzenia, więc zawsze zgłasza pozę w źródle, chyba że aplikacja zmieni ją za pomocą funkcji XRReferenceSpace.getOffsetReferenceSpace()
. W przykładzie jest to możliwe, aby umożliwić przesuwanie dotykowe kamery.
Zapętlanie klatek
Ogólnie rzecz biorąc, nic się nie zmienia od tego, co robiłem w sesji VR opisanej w moich wcześniejszych artykułach. Przekaż typ pokoju referencyjnego do funkcji XRFrame.getViewerPose()
.
Zwrócony XRViewerPose
będzie dotyczył bieżącego typu przestrzeni referencyjnej. Jeśli ustawisz wartość viewer
jako domyślną, strona będzie wyświetlać podgląd treści, zanim użytkownik poprosi użytkownika o zgodę na korzystanie z rzeczywistości rozszerzonej lub wirtualnej. Świadczy to o ważnej kwestii: treść wbudowana wykorzystuje tę samą pętlę klatek co treść przewijana, co zmniejsza ilość kodu do utrzymania.
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 zawiera tylko podstawowe informacje o implementowaniu treści interaktywnych w internecie. Znacznie więcej możliwości i przypadków użycia znajdziesz w przykładach korzystania z WebXR Device API organizacji Immersive Web zmniejszająca zasięg. Właśnie opublikowaliśmy artykuł z testu trafień, w którym wyjaśniamy, jak działa interfejs API służący do wykrywania powierzchni i umieszczania wirtualnych przedmiotów w widoku rzeczywistym z kamery. Możesz je przeglądać i oglądać na blogu web.dev, w którym w kolejnym roku znajdziesz kolejne artykuły.
Zdjęcie: David Grandmougin, Unsplash