Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/renderers/common/XRManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { warn } from '../../utils.js';

const _cameraLPos = /*@__PURE__*/ new Vector3();
const _cameraRPos = /*@__PURE__*/ new Vector3();
const _correctionQuaternion = /*@__PURE__*/ new Quaternion().setFromAxisAngle( new Vector3( 0, 1, 0 ), - Math.PI / 2 );

/**
* The XR manager is built on top of the WebXR Device API to
Expand Down Expand Up @@ -66,6 +67,16 @@ class XRManager extends EventDispatcher {
*/
this.cameraAutoUpdate = true;

/**
* Whether to apply a -90° Y-axis rotation correction to the XR camera for video textures.
* This corrects the orientation of video textures in WebXR projection layers.
* When enabled, this rotates the entire camera, affecting all rendered content.
*
* @type {boolean}
* @default false
*/
this.videoTextureCorrection = false;

/**
* The renderer.
*
Expand Down Expand Up @@ -1624,6 +1635,14 @@ function onAnimationFrame( time, frame ) {

camera.matrix.fromArray( view.transform.matrix );
camera.matrix.decompose( camera.position, camera.quaternion, camera.scale );

if ( this.videoTextureCorrection ) {

camera.quaternion.premultiply( _correctionQuaternion );
camera.matrix.compose( camera.position, camera.quaternion, camera.scale );

}

camera.projectionMatrix.fromArray( view.projectionMatrix );
camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert();
camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
Expand Down
21 changes: 20 additions & 1 deletion src/renderers/webxr/WebXRManager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { EventDispatcher } from '../../core/EventDispatcher.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
import { Quaternion } from '../../math/Quaternion.js';
import { Vector2 } from '../../math/Vector2.js';
import { Vector3 } from '../../math/Vector3.js';
import { Vector4 } from '../../math/Vector4.js';
Expand Down Expand Up @@ -102,6 +103,16 @@ class WebXRManager extends EventDispatcher {
*/
this.enabled = false;

/**
* Whether to apply a -90° Y-axis rotation correction to the XR camera for video textures.
* This corrects the orientation of video textures in WebXR projection layers.
* When enabled, this rotates the entire camera, affecting all rendered content.
*
* @type {boolean}
* @default false
*/
this.videoTextureCorrection = false;

/**
* Whether XR presentation is active or not.
*
Expand Down Expand Up @@ -912,7 +923,7 @@ class WebXRManager extends EventDispatcher {
// Animation Loop

let onAnimationFrameCallback = null;

const correctionQuaternion = new Quaternion().setFromAxisAngle( new Vector3( 0, 1, 0 ), - Math.PI / 2 );
function onAnimationFrame( time, frame ) {

pose = frame.getViewerPose( customReferenceSpace || referenceSpace );
Expand Down Expand Up @@ -982,6 +993,14 @@ class WebXRManager extends EventDispatcher {

camera.matrix.fromArray( view.transform.matrix );
camera.matrix.decompose( camera.position, camera.quaternion, camera.scale );

if ( scope.videoTextureCorrection ) {

camera.quaternion.premultiply( correctionQuaternion );
camera.matrix.compose( camera.position, camera.quaternion, camera.scale );

}

camera.projectionMatrix.fromArray( view.projectionMatrix );
camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert();
camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
Expand Down