Start · Sprachen · JavaScript · Referenz · new XRWebGLBinding()

new XRWebGLBinding()

Methode

Erzeugt ein <code>XRWebGLBinding</code>-Objekt, das eine WebXR-Sitzung mit einem WebGL-Kontext verbindet, z. B. für Composition Layers, Tiefen- oder Kameradaten.

seit JavaScript Experimentell: Chromium-Browser (Chrome/Edge 90+, Kategorie: webapi

Signatur

new XRWebGLBinding(session, context)

Beschreibung

Der Konstruktor XRWebGLBinding() erzeugt eine Verbindung (Binding) zwischen einer XRSession und einem WebGLRenderingContext bzw. WebGL2RenderingContext. Über dieses Objekt bekommst du GPU-seitige Ressourcen, die WebXR für diesen Kontext bereitstellt, also Texturen und Layer, in die direkt gerendert werden kann.

Du brauchst ein XRWebGLBinding vor allem in diesen Fällen:

  • WebXR Layers API: createProjectionLayer(), createQuadLayer(), createCylinderLayer(), createEquirectLayer(), createCubeLayer() sowie getViewSubImage()/getSubImage(), um die passende Farb- und Tiefentextur pro Frame zu bekommen.
  • Tiefenerkennung auf der GPU mit getDepthInformation(view) (Feature "depth-sensing").
  • Zugriff auf das Kamerabild mit getCameraImage(camera) (Feature "camera-access") in AR-Sitzungen.

Für das einfache Rendern reicht meistens der ältere XRWebGLLayer. XRWebGLBinding ist die modernere und flexiblere Alternative: Mehrere Layer lassen sich kombinieren, und der Compositor kann z. B. Text auf Quad-Layern schärfer darstellen. Wichtig: Der WebGL-Kontext muss XR-kompatibel sein. Das erreichst du mit { xrCompatible: true } beim Erzeugen des Kontexts oder durch Aufruf von gl.makeXRCompatible().

Parameter

Name Typ Default Beschreibung
$session Pflicht XRSession Die WebXR-Sitzung, an die der Kontext gebunden werden soll. Sie darf noch nicht beendet sein.
$context Pflicht WebGLRenderingContext | WebGL2RenderingContext Der WebGL-Kontext, mit dem gerendert wird. Er muss XR-kompatibel sein (xrCompatible: true oder makeXRCompatible()) und darf nicht verloren sein. Für viele Layer-Funktionen, etwa Texture Arrays, ist WebGL2 nötig.

Rückgabewert

Typ
XRWebGLBinding
Beschreibung
Ein neues XRWebGLBinding-Objekt, das Sitzung und WebGL-Kontext miteinander verbindet.

Beispiele

Binding für eine immersive VR-Sitzung erzeugen

const startXR = async () => {
  if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-vr'))) {
    console.log('immersive-vr wird nicht unterstützt');
    return;
  }

  const session = await navigator.xr.requestSession('immersive-vr', {
    optionalFeatures: ['layers']
  });

  const canvas = document.createElement('canvas');
  // Kontext direkt XR-kompatibel anlegen
  const gl = canvas.getContext('webgl2', { xrCompatible: true });

  const binding = new XRWebGLBinding(session, gl);
  console.log(binding instanceof XRWebGLBinding);
  return { session, gl, binding };
};

// Muss durch eine Nutzeraktion ausgelöst werden
document.querySelector('#enter-vr').addEventListener('click', startXR);
true

Projection Layer anlegen und pro Frame rendern (WebXR Layers)

const runWithLayers = async () => {
  const session = await navigator.xr.requestSession('immersive-vr', {
    requiredFeatures: ['layers']
  });
  const gl = document.createElement('canvas').getContext('webgl2');
  await gl.makeXRCompatible();

  const binding = new XRWebGLBinding(session, gl);
  const layer = binding.createProjectionLayer({
    textureType: 'texture',
    depthFormat: gl.DEPTH_COMPONENT24
  });
  session.updateRenderState({ layers: [layer] });

  const refSpace = await session.requestReferenceSpace('local');
  const fb = gl.createFramebuffer();

  const onFrame = (time, frame) => {
    session.requestAnimationFrame(onFrame);
    const pose = frame.getViewerPose(refSpace);
    if (!pose) return;

    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    for (const view of pose.views) {
      const sub = binding.getViewSubImage(layer, view);
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
        gl.TEXTURE_2D, sub.colorTexture, 0);
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
        gl.TEXTURE_2D, sub.depthStencilTexture, 0);
      const { x, y, width, height } = sub.viewport;
      gl.viewport(x, y, width, height);
      gl.clearColor(0.1, 0.2, 0.3, 1);
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
      // ... Szene für diese Ansicht zeichnen
    }
  };
  session.requestAnimationFrame(onFrame);
};

Kamerabild in einer AR-Sitzung als WebGL-Textur holen

const startAR = async () => {
  const session = await navigator.xr.requestSession('immersive-ar', {
    requiredFeatures: ['camera-access']
  });
  const gl = document.createElement('canvas').getContext('webgl2', { xrCompatible: true });
  session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });

  const binding = new XRWebGLBinding(session, gl);
  const refSpace = await session.requestReferenceSpace('local');

  const onFrame = (time, frame) => {
    session.requestAnimationFrame(onFrame);
    const pose = frame.getViewerPose(refSpace);
    if (!pose) return;
    for (const view of pose.views) {
      if (view.camera) {
        const cameraTexture = binding.getCameraImage(view.camera);
        // cameraTexture ist eine WebGLTexture, nur in diesem Frame gültig
        console.log(view.camera.width, view.camera.height);
      }
    }
  };
  session.requestAnimationFrame(onFrame);
};
z. B. 1280 720