Augmented Reality: Vielleicht kennen Sie es schon

Wenn Sie die WebXR Device API bereits verwendet haben, sind Sie schon fast am Ziel.

Joe Medley
Joe Medley

Die WebXR Device API wurde im Herbst in Chrome 79 eingeführt. Wie bereits erwähnt, ist die Implementierung der API in Chrome noch in Arbeit. Wir freuen uns, mitteilen zu können, dass einige der Arbeiten bereits abgeschlossen sind. In Chrome 81 gibt es zwei neue Funktionen:

In diesem Artikel geht es um Augmented Reality. Wenn Sie die WebXR Device API bereits verwendet haben, werden Sie erfreut sein, dass es nur sehr wenige Neuigkeiten gibt. Das Starten einer WebXR-Sitzung funktioniert weitgehend genauso. Das Ausführen einer Frame-Schleife funktioniert im Wesentlichen genauso. Die Unterschiede liegen in den Konfigurationen, die es ermöglichen, Inhalte für Augmented Reality angemessen darzustellen. Wenn Sie mit den grundlegenden Konzepten von WebXR nicht vertraut sind, sollten Sie meine früheren Beiträge zur WebXR Device API lesen oder zumindest mit den darin behandelten Themen vertraut sein. Sie sollten wissen, wie Sie eine Sitzung anfordern und betreten und wie Sie eine Frame-Schleife ausführen.

Informationen zu Treffertests finden Sie im Artikel Virtuelle Objekte in realen Ansichten positionieren. Der Code in diesem Artikel basiert auf dem Beispiel für eine immersive AR-Sitzung (Demo, Quellcode) aus den WebXR Device API-Beispielen der Immersive Web Working Group.

Bevor Sie sich mit dem Code befassen, sollten Sie das Beispiel für eine immersive AR-Sitzung mindestens einmal verwenden. Sie benötigen ein modernes Android-Smartphone mit Chrome 81 oder höher.

Wozu ist sie nützlich?

Augmented Reality ist eine wertvolle Ergänzung für viele bestehende oder neue Webseiten, da AR-Use-Cases ohne Verlassen des Browsers implementiert werden können. So können Nutzer beispielsweise auf Bildungswebsites lernen und potenzielle Käufer sich beim Einkaufen Objekte in ihrem Zuhause vorstellen.

Betrachten Sie den zweiten Anwendungsfall. Stellen Sie sich vor, Sie simulieren das Platzieren einer lebensgroßen Darstellung eines virtuellen Objekts in einer realen Szene. Nach dem Platzieren bleibt das Bild auf der ausgewählten Oberfläche, wird in der Größe angezeigt, die es hätte, wenn sich das tatsächliche Objekt auf dieser Oberfläche befände, und ermöglicht es dem Nutzer, sich um das Bild herum zu bewegen und sich ihm zu nähern oder von ihm zu entfernen. So erhalten die Betrachter ein besseres Verständnis des Objekts als mit einem zweidimensionalen Bild.

Ich greife etwas vor. Um das zu tun, was ich beschrieben habe, benötigen Sie AR-Funktionen und eine Möglichkeit, Oberflächen zu erkennen. In diesem Artikel geht es um Ersteres. Der zugehörige Artikel zur WebXR Hit Test API (oben verlinkt) behandelt Letzteres.

Sitzung anfordern

Das Anfordern einer Sitzung funktioniert ähnlich wie zuvor. Prüfe zuerst, ob der gewünschte Sitzungstyp auf dem aktuellen Gerät verfügbar ist. Rufe dazu xr.isSessionSupported() auf. Statt wie zuvor 'immersive-vr' anzufordern, fordern Sie 'immersive-ar' an.

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
  }
}

Wie bisher wird dadurch die Schaltfläche „AR starten“ aktiviert. Wenn der Nutzer darauf klickt, rufe xr.requestSession() auf und übergebe dabei auch '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();
  }
}

Eine praktische Property

Sie haben wahrscheinlich bemerkt, dass ich im letzten Codebeispiel zwei Zeilen hervorgehoben habe. Das XRSession-Objekt hat anscheinend eine Property namens isImmersive. Das ist ein praktisches Attribut, das ich selbst erstellt habe und das nicht Teil der Spezifikation ist. Ich verwende es später, um zu entscheiden, was dem Betrachter angezeigt werden soll. Warum ist dieses Attribut nicht Teil der API? Da diese Property in Ihrer App möglicherweise anders erfasst werden muss, haben die Autoren der Spezifikation beschlossen, die API möglichst übersichtlich zu gestalten.

Sitzung starten

Erinnern Sie sich daran, wie onSessionStarted() in meinem vorherigen Artikel aussah:

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);
  });
}

Ich muss noch ein paar Dinge hinzufügen, um das Rendern von Augmented Reality zu berücksichtigen. Hintergrund deaktivieren Das ist das erste Mal, dass ich meine praktische Property verwende.

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);
  });

}

Referenzbereiche

In meinen früheren Artikeln wurde nur kurz auf Referenzbereiche eingegangen. Im Beispiel, das ich beschreibe, werden zwei davon verwendet. Es ist also an der Zeit, diese Lücke zu schließen.

Ein Referenzraum beschreibt die Beziehung zwischen der virtuellen Welt und der physischen Umgebung des Nutzers. Dazu gehören:

  • Der Ursprung des Koordinatensystems, das zum Ausdruck von Positionen in der virtuellen Welt verwendet wird.
  • Gibt an, ob sich der Nutzer innerhalb dieses Koordinatensystems bewegen soll.
  • Ob dieses Koordinatensystem vorab festgelegte Grenzen hat. In den hier gezeigten Beispielen werden keine Koordinatensysteme mit vordefinierten Grenzen verwendet.

Für alle Referenzräume gibt die X-Koordinate links und rechts an, die Y-Koordinate oben und unten und die Z-Koordinate vor und zurück. Positive Werte stehen für „rechts“, „oben“ und „zurück“.

Die von XRFrame.getViewerPose() zurückgegebenen Koordinaten hängen vom angeforderten Referenzraumtyp ab. Mehr dazu später, wenn wir über die Frame-Schleife sprechen. Jetzt müssen wir einen Referenztyp auswählen, der für Augmented Reality geeignet ist. Hier wird wieder meine praktische Property verwendet.

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);
  });
}

Wenn Sie sich das Beispiel für eine immersive AR-Sitzung angesehen haben, haben Sie vielleicht bemerkt, dass die Szene anfangs statisch ist und nicht Augmented Reality verwendet. Sie können mit dem Finger ziehen und wischen, um sich in der Szene zu bewegen. Wenn Sie auf „AR STARTEN“ klicken, wird der Hintergrund ausgeblendet und Sie können sich durch die Szene bewegen, indem Sie das Gerät bewegen. Für die Modi werden unterschiedliche Referenzraumtypen verwendet. Im hervorgehobenen Text oben ist zu sehen, wie das geht. Dabei werden die folgenden Referenztypen verwendet:

local: Der Ursprung befindet sich an der Position des Betrachters zum Zeitpunkt der Sitzungserstellung. Das bedeutet, dass die Funktion nicht unbedingt eine klar definierte Untergrenze hat und die genaue Position des Ursprungs je nach Plattform variieren kann. Es gibt zwar keine vordefinierten Grenzen für den Bereich, aber es wird davon ausgegangen, dass Inhalte ohne andere Bewegung als Drehung angesehen werden können. Wie Sie an unserem eigenen AR-Beispiel sehen können, ist es unter Umständen möglich, sich im Raum zu bewegen.

viewer: Dieser Abstand wird am häufigsten für Inhalte verwendet, die inline auf der Seite angezeigt werden. Er passt sich dem Anzeigegerät an. Wenn es an getViewerPose übergeben wird, erfolgt kein Tracking und es wird immer eine Pose am Ursprung gemeldet, es sei denn, die Anwendung ändert sie mit XRReferenceSpace.getOffsetReferenceSpace(). Im Beispiel wird dies verwendet, um das Touch-basierte Schwenken der Kamera zu ermöglichen.

Frame-Schleife ausführen

Konzeptionell ändert sich nichts an dem, was ich in der VR-Sitzung getan habe, die in meinen vorherigen Artikeln beschrieben wurde. Übergeben Sie den Typ des Referenzbereichs an XRFrame.getViewerPose(). Die zurückgegebene XRViewerPose bezieht sich auf den aktuellen Referenzraumtyp. Wenn Sie viewer als Standard festlegen, können auf einer Seite Inhaltsvorschauen angezeigt werden, bevor die Nutzereinwilligung für AR oder VR eingeholt wird. Das verdeutlicht einen wichtigen Punkt: Für die Inline-Inhalte wird dieselbe Frame-Schleife verwendet wie für die immersiven Inhalte. Dadurch wird die Menge an Code reduziert, die gepflegt werden muss.

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(refSpaceType);
  if (xrViewerPose) {
    // Render based on the pose.
  }
}

Fazit

In dieser Artikelreihe werden nur die Grundlagen der Implementierung von immersiven Inhalten im Web behandelt. Viele weitere Funktionen und Anwendungsfälle finden Sie in den WebXR Device API-Beispielen der Immersive Web Working Group. Außerdem haben wir gerade einen Artikel zu Hittests veröffentlicht, in dem eine API zum Erkennen von Oberflächen und Platzieren virtueller Elemente in einer realen Kameraansicht erläutert wird. Sehen Sie sich diese an und achten Sie im Laufe des Jahres auf weitere Artikel im web.dev-Blog.

Foto von David Grandmougin auf Unsplash