Start · Sprachen · JavaScript · Referenz · HMDVRDevice.setFieldOfView()

HMDVRDevice.setFieldOfView()

Methode

Legt das Sichtfeld (<code>VRFieldOfView</code>) für das linke und rechte Auge eines Head-Mounted-Displays sowie die Near- und Far-Clipping-Ebenen fest.

seit JavaScript Veraltet: nur experimentelle WebVR-1.0-Vorgänger-A deprecated seit ja Kategorie: webapi

Signatur

HMDVRDevice.prototype.setFieldOfView(leftFOV, rightFOV, zNear, zFar)

Beschreibung

Die Methode setFieldOfView() gehört zum Interface HMDVRDevice der frühen, experimentellen WebVR-API. Damit ließ sich das Sichtfeld (Field of View, FOV) festlegen, mit dem ein VR-Headset die Szene für jedes Auge darstellt. Das linke und das rechte Auge bekommen jeweils ein eigenes VRFieldOfView-Objekt. Übergibt man für beide Augen dasselbe Objekt, stellt man beide gleichzeitig ein.

Ein VRFieldOfView beschreibt das Sichtfeld über vier Winkel in Grad: upDegrees, rightDegrees, downDegrees und leftDegrees. Mit zNear und zFar legt man zusätzlich fest, ab welcher Entfernung Objekte gezeichnet werden und ab welcher nicht mehr (Near- und Far-Clipping-Ebene). Das entspricht den Werten, die man auch für eine Perspektiv-Projektionsmatrix in WebGL braucht.

Gedacht war die Methode z. B. für eine eigene Zoom-Stufe oder ein kleineres Sichtfeld, um Rechenleistung zu sparen. Die zulässigen Grenzen findet man über HMDVRDevice.getEyeParameters() heraus. Das zurückgegebene VREyeParameters-Objekt enthält minimumFieldOfView, maximumFieldOfView, recommendedFieldOfView und currentFieldOfView.

Wichtig: Die gesamte API ist veraltet und wird von keinem aktuellen Browser mehr unterstützt. Für neue Projekte ist die WebXR Device API das Mittel der Wahl. Dort gibt die Laufzeitumgebung das Sichtfeld über XRView.projectionMatrix vor.

Parameter

Name Typ Default Beschreibung
$leftFOV Pflicht VRFieldOfView Sichtfeld für das linke Auge (Winkel in Grad für oben, rechts, unten und links).
$rightFOV Pflicht VRFieldOfView Sichtfeld für das rechte Auge. Mit demselben Objekt wie bei leftFOV stellt man beide Augen gleich ein.
$zNear number 0.01 Abstand der Near-Clipping-Ebene zum Betrachter. Objekte, die näher liegen, werden nicht gezeichnet.
$zFar number 10000.0 Abstand der Far-Clipping-Ebene zum Betrachter. Objekte, die weiter entfernt liegen, werden nicht gezeichnet.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Das neue Sichtfeld kann man danach über getEyeParameters(eye).currentFieldOfView prüfen.

Beispiele

Gleiches Sichtfeld für beide Augen setzen

// Alte WebVR-API: HMD suchen und ein symmetrisches Sichtfeld von 45° setzen
const initHMD = async () => {
  if (!navigator.getVRDevices) {
    console.log('WebVR (alt) wird nicht unterstützt.');
    return;
  }
  const devices = await navigator.getVRDevices();
  const hmd = devices.find((d) => d instanceof HMDVRDevice);
  if (!hmd) {
    console.log('Kein Headset gefunden.');
    return;
  }
  const fov = new VRFieldOfView(45, 45, 45, 45); // oben, rechts, unten, links
  hmd.setFieldOfView(fov, fov, 0.01, 10000);
  console.log(hmd.getEyeParameters('left').currentFieldOfView.upDegrees);
};

initHMD();
45

Zoom-Regler innerhalb der zulässigen Grenzen

// Sichtfeld per Faktor verkleinern (Zoom), ohne das Minimum zu unterschreiten
const applyZoom = (hmd, factor) => {
  const scaleEye = (eye) => {
    const p = hmd.getEyeParameters(eye);
    const rec = p.recommendedFieldOfView;
    const min = p.minimumFieldOfView;
    const clamp = (v, m) => Math.max(v * factor, m);
    return new VRFieldOfView(
      clamp(rec.upDegrees, min.upDegrees),
      clamp(rec.rightDegrees, min.rightDegrees),
      clamp(rec.downDegrees, min.downDegrees),
      clamp(rec.leftDegrees, min.leftDegrees)
    );
  };
  hmd.setFieldOfView(scaleEye('left'), scaleEye('right'));
};

// Aufruf, z. B. aus einem Range-Input:
// document.querySelector('#zoom').addEventListener('input', (e) => applyZoom(hmd, Number(e.target.value)));

Moderner Ersatz: Projektion in WebXR auslesen

// In WebXR gibt die Laufzeitumgebung das Sichtfeld vor und liefert es als Projektionsmatrix
const startXR = async (gl) => {
  if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-vr'))) {
    console.log('immersive-vr nicht verfügbar');
    return;
  }
  const session = await navigator.xr.requestSession('immersive-vr');
  session.updateRenderState({ depthNear: 0.01, depthFar: 10000 }); // entspricht zNear/zFar
  const refSpace = await session.requestReferenceSpace('local');
  session.requestAnimationFrame(function onFrame(time, frame) {
    const pose = frame.getViewerPose(refSpace);
    pose?.views.forEach((view) => {
      // view.projectionMatrix enthält das Sichtfeld je Auge
    });
    session.requestAnimationFrame(onFrame);
  });
};

// Wichtig · Fallstricke

  • Veraltet und entfernt: HMDVRDevice, navigator.getVRDevices() und VRFieldOfView gab es nur in experimentellen Browser-Versionen (Firefox Nightly, spezielle Chromium-Builds). Sie wurden erst durch WebVR 1.1 (VRDisplay) und dann durch WebXR ersetzt. In aktuellen Browsern führt der Aufruf zu einem ReferenceError oder TypeError. Deshalb vorher immer prüfen, ob die API vorhanden ist.
  • Werte außerhalb von minimumFieldOfView bzw. maximumFieldOfView wurden je nach Implementierung begrenzt oder ignoriert. Deshalb vorher getEyeParameters() auswerten.
  • Ein zu großes Sichtfeld verzerrt das Bild, ein asymmetrisch falsch gesetztes Sichtfeld kann Übelkeit auslösen (Simulator-Sickness). Im Zweifel recommendedFieldOfView verwenden.
  • Ein sehr kleines zNear im Verhältnis zu zFar verringert die Genauigkeit des Tiefenpuffers und führt zu Z-Fighting (flackernde Flächen).
  • In WebXR lässt sich das Sichtfeld nicht frei setzen. Einstellen kann man nur depthNear und depthFar über XRSession.updateRenderState().