Auf dieser Seite erfahren Sie, wie Sie mit WebXR eine einfache immersive AR-Anwendung erstellen.
Sie benötigen eine WebXR-kompatible Entwicklungsumgebung.
HTML-Seite erstellen
WebXR erfordert eine Nutzerinteraktion, um eine Sitzung zu starten.
Erstellen Sie eine Schaltfläche, die activateXR()
aufruft. Nach dem Laden der Seite kann der Nutzer diese Schaltfläche verwenden, um das AR-Erlebnis zu starten.
Erstellen Sie eine neue Datei mit dem Namen index.html
und fügen Sie den folgenden HTML-Code hinzu:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Hello WebXR!</title>
<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
</head>
<body>
<!-- Starting an immersive WebXR session requires user interaction.
We start this one with a simple button. -->
<button onclick="activateXR()">Start Hello WebXR</button>
<script>
async function activateXR() {
// Add a canvas element and initialize a WebGL context that is compatible with WebXR.
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const gl = canvas.getContext("webgl", {xrCompatible: true});
// To be continued in upcoming steps.
}
</script>
</body>
</html>
Third.js initialisieren
Beim Drücken der Starttaste passiert nicht viel. Zum Einrichten einer 3D-Umgebung können Sie eine Rendering-Bibliothek verwenden, um eine Szene darzustellen.
In diesem Beispiel verwenden Sie three.js
, eine JavaScript-3D-Renderingbibliothek, die einen WebGL-Renderer bereitstellt. Three.js
übernimmt das Rendering, die Kameras und Szenendiagramme, was die Darstellung von 3D-Inhalten im Web vereinfacht.
Szene erstellen
Eine 3D-Umgebung wird im Allgemeinen als Szene modelliert. Erstellen Sie ein THREE.Scene
, das AR-Elemente enthält.
Mit dem folgenden Code können Sie ein unbeleuchtetes farbiges Feld in AR betrachten.
Fügen Sie diesen Code am Ende der Funktion activateXR()
ein:
const scene = new THREE.Scene();
// The cube will have a different color on each side.
const materials = [
new THREE.MeshBasicMaterial({color: 0xff0000}),
new THREE.MeshBasicMaterial({color: 0x0000ff}),
new THREE.MeshBasicMaterial({color: 0x00ff00}),
new THREE.MeshBasicMaterial({color: 0xff00ff}),
new THREE.MeshBasicMaterial({color: 0x00ffff}),
new THREE.MeshBasicMaterial({color: 0xffff00})
];
// Create the cube and add it to the demo scene.
const cube = new THREE.Mesh(new THREE.BoxBufferGeometry(0.2, 0.2, 0.2), materials);
cube.position.set(1, 1, 1);
scene.add(cube);
Rendering mit three.js einrichten
Damit Sie diese Szene im AR-Modus ansehen können, benötigen Sie einen Renderer und eine Kamera. Der Renderer verwendet WebGL, um deine Szene auf dem Bildschirm zu zeichnen. Die Kamera beschreibt den Darstellungsbereich, von dem aus die Szene betrachtet wird.
Fügen Sie diesen Code am Ende der Funktion activateXR()
ein:
// Set up the WebGLRenderer, which handles rendering to the session's base layer.
const renderer = new THREE.WebGLRenderer({
alpha: true,
preserveDrawingBuffer: true,
canvas: canvas,
context: gl
});
renderer.autoClear = false;
// The API directly updates the camera matrices.
// Disable matrix auto updates so three.js doesn't attempt
// to handle the matrices independently.
const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;
XRSession erstellen
Der Einstiegspunkt zu WebXR erfolgt über XRSystem.requestSession()
. Mit dem Modus „immersive-ar
“ lassen sich gerenderte Inhalte in einer realen Umgebung ansehen.
Ein XRReferenceSpace
beschreibt das Koordinatensystem, das für Objekte in der virtuellen Welt verwendet wird.
Der 'local'
-Modus eignet sich am besten für ein AR-Erlebnis mit einem Referenzraum, der einen Ursprung in der Nähe des Zuschauers und stabiles Tracking hat.
Fügen Sie diesen Code am Ende der Funktion activateXR()
ein, um XRSession
und XRReferenceSpace
zu erstellen:
// Initialize a WebXR session using "immersive-ar".
const session = await navigator.xr.requestSession("immersive-ar");
session.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');
Szene rendern
Jetzt können Sie die Szene rendern. XRSession.requestAnimationFrame()
plant einen Callback, der ausgeführt wird, wenn der Browser einen Frame zeichnen kann.
Rufen Sie während des Callbacks des Animationsframes XRFrame.getViewerPose()
auf, um die Position des Betrachters relativ zum lokalen Koordinatenraum zu erhalten.
Sie wird verwendet, um die Szenenbildkamera zu aktualisieren. Dabei ändert der Nutzer die virtuelle Welt, bevor der Renderer die Szene mit der aktualisierten Kamera zeichnet.
Fügen Sie diesen Code am Ende der Funktion activateXR()
ein:
// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
// Queue up the next draw request.
session.requestAnimationFrame(onXRFrame);
// Bind the graphics framebuffer to the baseLayer's framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer)
// Retrieve the pose of the device.
// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
const pose = frame.getViewerPose(referenceSpace);
if (pose) {
// In mobile AR, we only have one view.
const view = pose.views[0];
const viewport = session.renderState.baseLayer.getViewport(view);
renderer.setSize(viewport.width, viewport.height)
// Use the view's transform matrix and projection matrix to configure the THREE.camera.
camera.matrix.fromArray(view.transform.matrix)
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
// Render the scene with THREE.WebGLRenderer.
renderer.render(scene, camera)
}
}
session.requestAnimationFrame(onXRFrame);
Hello WebXR ausführen
Rufen Sie die WebXR-Datei auf Ihrem Gerät auf. Sie sollten einen farbigen Würfel von allen Seiten sehen können.
Treffertest hinzufügen
Eine gängige Methode zur Interaktion mit der AR-Welt ist ein Treffertest, bei dem eine Schnittstelle zwischen einem Strahl und einer realen Geometrie ermittelt wird. In Hello WebXR platzieren Sie eine Sonnenblume mithilfe eines Treffertests in der virtuellen Welt.
Demo-Cube entfernen
Entferne den unbeleuchteten Kubus und ersetze ihn durch eine Szene, in der Beleuchtung zu sehen ist:
const scene = new THREE.Scene();
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
directionalLight.position.set(10, 15, 10);
scene.add(directionalLight);
Funktion „hit-test
“ verwenden
Fordere zum Initialisieren der Treffertestfunktion eine Sitzung mit der Funktion hit-test
an. Suche das vorherige requestSession()
-Fragment und füge hit-test
hinzu:
const session = await navigator.xr.requestSession("immersive-ar", {requiredFeatures: ['hit-test']});
Modellladeprogramm hinzufügen
Derzeit enthält die Szene nur einen farbigen Würfel. Fügen Sie ein Modellladeprogramm hinzu, mit dem GLTF-Modelle geladen werden können.
Fügen Sie im <head>
-Tag Ihres Dokuments three.js' GLTFLoader
hinzu.
<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>
GLTF-Modelle laden
Laden Sie mithilfe des Modellladeprogramms aus dem vorherigen Schritt ein Zielfadenkreuz und eine Sonnenblume aus dem Web.
Fügen Sie diesen Code oberhalb von onXRFrame
ein:
const loader = new THREE.GLTFLoader();
let reticle;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf", function(gltf) {
reticle = gltf.scene;
reticle.visible = false;
scene.add(reticle);
})
let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
flower = gltf.scene;
});
// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
Treffertestquelle erstellen
Zum Berechnen von Kreuzungen mit realen Objekten erstellen Sie mit XRSession.requestHitTestSource()
einen XRHitTestSource
.
Der für die Treffertests verwendete Strahl hat den Referenzraum viewer
als Ursprung. Das bedeutet, dass der Treffertest von der Mitte des Darstellungsbereichs aus durchgeführt wird.
Fügen Sie den folgenden Code hinzu, nachdem Sie den Referenzraum local
erstellt haben, um eine Treffertestquelle zu erstellen:
// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');
// Create another XRReferenceSpace that has the viewer as the origin.
const viewerSpace = await session.requestReferenceSpace('viewer');
// Perform hit testing using the viewer as origin.
const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
Angezieltes Fadenkreuz zeichnen
Fügen Sie dem Motiv ein Fadenkreuz hinzu, um zu verdeutlichen, wo die Sonnenblume platziert wird. Dieses Fadenkreuz scheint an realen Oberflächen zu kleben und zeigt an, wo die Sonnenblume verankert sein wird.
XRFrame.getHitTestResults
gibt ein Array von XRHitTestResult
zurück und zeigt Schnittpunkte mit realer Geometrie an.
Verwenden Sie diese Schnittpunkte, um das Zielfadenkreuz in jedem Frame zu positionieren.
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
const hitTestResults = frame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0 && reticle) {
const hitPose = hitTestResults[0].getPose(referenceSpace);
reticle.visible = true;
reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
reticle.updateMatrixWorld(true);
}
Interaktionen durch Tippen hinzufügen
XRSession
empfängt select
-Ereignisse, wenn der Nutzer eine primäre Aktion ausführt.
Bei einer AR-Sitzung entspricht dies einem Tippen auf den Bildschirm.
Lassen Sie eine neue Sonnenblume anzeigen, wenn der Nutzer auf den Bildschirm tippt, indem Sie diesen Code während der Initialisierung hinzufügen:
let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
flower = gltf.scene;
});
session.addEventListener("select", (event) => {
if (flower) {
const clone = flower.clone();
clone.position.copy(reticle.position);
scene.add(clone);
}
});
Treffertest testen
Verwenden Sie Ihr Mobilgerät, um die Seite aufzurufen. Nachdem WebXR die Umgebung analysiert hat, sollte das Fadenkreuz auf realen Oberflächen erscheinen. Tippe auf das Display, um eine Sonnenblume zu platzieren, die von allen Seiten zu sehen ist.
Nächste Schritte
- Lesen Sie die WebXR Device API Specification.
- Weitere Informationen finden Sie in der WebXR-Referenzdokumentation in den MDN-Webdokumenten.
- Probieren Sie WebXR Samples aus.
- Mit der WebXR Device API eine Augmented-Reality-App (AR-App) erstellen (Codelab)