Back openDesk Edu for a sovereign, open-source education â every vote counts.
Vote nowSave products you love by clicking the heart icon.
Design principles and implementation patterns for building intuitive, accessible spatial user interfaces in WebXR â from layout and typography to gestures and feedback.
Das WebXR-Ăkosystem im Jahr 2026 erstreckt sich ĂŒber eine Vielzahl von GerĂ€ten â von der Meta Quest 3 und Apple Vision Pro bis hin zu mobilen AR-Handhelds und Desktop-VR-Headsets. Jede Plattform verfĂŒgt ĂŒber einzigartige Funktionen, Eingabemethoden und Performance-Profile. Die Entwicklung von plattformĂŒbergreifendem WebXR erfordert einen Ansatz der progressiven Erweiterung (Progressive Enhancement) und keine Einheitslösung.
| GerÀt | Eingabe | Tracking | Performance | WebXR-Support |
|---|---|---|---|---|
| Meta Quest 3/3S | Touch-Controller, HĂ€nde | Inside-out 6DOF | Mittel (XR2 Gen 2) | Volles WebXR |
| Apple Vision Pro | Augen, HĂ€nde, Stimme | Inside-out, Eye-Tracking | Hoch (M2 + R1) | WebXR via Safari 18 |
| Mobile AR (iOS/Android) | Touchscreen | SLAM | Variabel (GPU) | Nur WebXR AR |
| PlayStation VR2 | PSVR2-Controller | Inside-out | Hoch | WebXR via Browser |
| Desktop VR (Index, etc.) | Motion-Controller | Lighthouse/Inside-out | Hoch | Volles WebXR |
Setzen Sie keine Funktionen voraus â erkennen Sie diese zur Laufzeit:
async function detectXRCapabilities() {
if (!navigator.xr) return { supported: false, reason: "No WebXR" };
const supportedModes = {
inline: await navigator.xr.isSessionSupported("inline"),
immersiveVR: await navigator.xr.isSessionSupported("immersive-vr"),
immersiveAR: await navigator.xr.isSessionSupported("immersive-ar"),
};
// Detect specific features
const features = {
handTracking: supportedModes.immersiveVR && "hand-tracking" in XRSession.prototype,
hitTest: "XRHitTestSource" in window,
anchors: "XRAnchor" in window,
depthSensing: "XRDepthInformation" in window,
layers: "XRCompositionLayer" in window,
eyeTracking: "XREye" in window,
};
return { supportedModes, features };
}
Schichten Sie die Funktionen von grundlegend bis fortgeschritten:
function XRApp() {
const [capabilities, setCapabilities] = useState<XRCapabilities | null>(null);
useEffect(() => {
detectXRCapabilities().then(setCapabilities);
}, []);
if (!capabilities) return <LoadingScreen />;
if (!capabilities.supportedModes.immersiveVR && !capabilities.supportedModes.immersiveAR) {
return <Fallback3DView />;
}
return (
<XRRenderer capabilities={capabilities}>
<SpatialUI inputMethod={detectInputMethod(capabilities)} />
<SceneGraph quality={selectQuality(capabilities)} />
</XRRenderer>
);
}
Abstrahieren Sie die Eingabe, damit die UI-Logik nicht vom GerÀt abhÀngt:
type XRInputEvent = {
position: THREE.Vector3;
direction?: THREE.Quaternion;
type: "select" | "squeeze" | "pinch" | "gaze" | "touch";
source: "controller" | "hand" | "gaze" | "screen";
};
function createInputManager(capabilities: XRCapabilities) {
const input$ = new Subject<XRInputEvent>();
if (capabilities.features.handTracking) {
setupHandTracking(input$);
}
if (capabilities.supportedModes.immersiveVR) {
setupControllers(input$);
}
// Always add gaze fallback
setupGazeInput(input$);
return input$;
}
Die Quest bietet einen exzellenten WebXR-Support, verfĂŒgt jedoch ĂŒber eine begrenzte GPU. Zentrale Strategien:
// Quest-specific optimization: fixed foveated rendering
const xrSession = await navigator.xr.requestSession("immersive-vr", {
optionalFeatures: ["foveation"],
});
if (xrSession.updateRenderState) {
xrSession.updateRenderState({
foveationLevel: 0.5, // 0=off, 1=maximum
});
}
Nutzen Sie Passthrough AR auf der Quest 3 fĂŒr Mixed-Reality-Erlebnisse:
const session = await navigator.xr.requestSession("immersive-ar", {
optionalFeatures: ["passthrough"],
});
Vision Pro Safari 18 supports WebXR with unique constraints:
// Vision Pro: use eye tracking for precision targeting
const eyeGazeSource = await session.requestReferenceSpace("local");
const eyeTracker = await session.requestAnimationFrame((time, frame) => {
const pose = frame.getPose(eyeGazeSpace, referenceSpace);
if (pose) highlightTarget(pose.transform.position);
});
// Vision Pro: handle direct touch input
element.addEventListener("touchstart", (e) => {
// Vision Pro reports touches as pointer events from eye + pinch
});
Key Vision Pro considerations:
Mobile AR is the widest reach but most constrained:
if (sessionMode === "immersive-ar" && isMobileDevice()) {
// Mobile AR: flat surface placement is the primary interaction
session.requestHitTestSource({ space: viewerSpace });
// Limit draw calls to ~30
// Use half-resolution rendering
gl.setSize(window.innerWidth / 2, window.innerHeight / 2);
}
Scale rendering quality based on device capability:
function selectQuality(device: XRCapabilities): QualitySettings {
const gpuTier = detectGPUTier();
if (gpuTier === "high") {
return { pixelRatio: 1, shadows: true, postProcessing: true, msaa: 4 };
}
if (gpuTier === "medium") {
return { pixelRatio: 0.75, shadows: false, postProcessing: false, msaa: 2 };
}
// Low-end (mobile)
return { pixelRatio: 0.5, shadows: false, postProcessing: false, msaa: 1 };
}
Test across devices in CI:
jobs:
webxr-test:
strategy:
matrix:
device: [quest-3, vision-pro, mobile-ios, mobile-android]
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
- uses: WebXR-Test/action@v2
with:
device: ${{ matrix.device }}
url: https://staging.example.com/xr-app
tests: tests/webxr/
Always provide a non-XR experience:
function Fallback3DView() {
return (
<div className="relative h-screen w-full">
<canvas ref={canvasRef} /> {/* Three.js fallback */}
<div className="absolute bottom-8 left-1/2 -translate-x-1/2">
<p className="text-sm text-gray-500">
WebXR not supported on this device. View the 3D scene in your browser instead.
</p>
</div>
</div>
);
}
Bevor Sie plattformĂŒbergreifendes XR veröffentlichen:
PlattformĂŒbergreifendes WebXR im Jahr 2026 bedeutet, eine gröĂere Auswahl an GerĂ€ten als je zuvor zu unterstĂŒtzen. Testen Sie auf echter Hardware, nicht nur mit Emulatoren.