|
@@ -9,6 +9,7 @@ import { Vector4 } from '../../math/Vector4.js';
|
|
|
import { WebXRController } from '../webxr/WebXRController.js';
|
|
import { WebXRController } from '../webxr/WebXRController.js';
|
|
|
import { AddEquation, BackSide, CustomBlending, DepthFormat, DepthStencilFormat, FrontSide, RGBAFormat, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, ZeroFactor } from '../../constants.js';
|
|
import { AddEquation, BackSide, CustomBlending, DepthFormat, DepthStencilFormat, FrontSide, RGBAFormat, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, ZeroFactor } from '../../constants.js';
|
|
|
import { DepthTexture } from '../../textures/DepthTexture.js';
|
|
import { DepthTexture } from '../../textures/DepthTexture.js';
|
|
|
|
|
+import { DepthArrayTexture } from '../../textures/DepthArrayTexture.js';
|
|
|
import { XRRenderTarget } from './XRRenderTarget.js';
|
|
import { XRRenderTarget } from './XRRenderTarget.js';
|
|
|
import { CylinderGeometry } from '../../geometries/CylinderGeometry.js';
|
|
import { CylinderGeometry } from '../../geometries/CylinderGeometry.js';
|
|
|
import { PlaneGeometry } from '../../geometries/PlaneGeometry.js';
|
|
import { PlaneGeometry } from '../../geometries/PlaneGeometry.js';
|
|
@@ -32,8 +33,9 @@ class XRManager extends EventDispatcher {
|
|
|
* Constructs a new XR manager.
|
|
* Constructs a new XR manager.
|
|
|
*
|
|
*
|
|
|
* @param {Renderer} renderer - The renderer.
|
|
* @param {Renderer} renderer - The renderer.
|
|
|
|
|
+ * @param {boolean} [multiview=false] - Enables multiview if the device supports it.
|
|
|
*/
|
|
*/
|
|
|
- constructor( renderer ) {
|
|
|
|
|
|
|
+ constructor( renderer, multiview = false ) {
|
|
|
|
|
|
|
|
super();
|
|
super();
|
|
|
|
|
|
|
@@ -354,6 +356,26 @@ class XRManager extends EventDispatcher {
|
|
|
*/
|
|
*/
|
|
|
this._useLayers = ( typeof XRWebGLBinding !== 'undefined' && 'createProjectionLayer' in XRWebGLBinding.prototype ); // eslint-disable-line compat/compat
|
|
this._useLayers = ( typeof XRWebGLBinding !== 'undefined' && 'createProjectionLayer' in XRWebGLBinding.prototype ); // eslint-disable-line compat/compat
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Whether the usage of multiview has been requested by the application or not.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @private
|
|
|
|
|
+ * @type {boolean}
|
|
|
|
|
+ * @default false
|
|
|
|
|
+ * @readonly
|
|
|
|
|
+ */
|
|
|
|
|
+ this._useMultiviewIfPossible = multiview;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Whether the usage of multiview is actually enabled. This flag only evaluates to `true`
|
|
|
|
|
+ * if multiview has been requested by the application and the `OVR_multiview2` is available.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @private
|
|
|
|
|
+ * @type {boolean}
|
|
|
|
|
+ * @readonly
|
|
|
|
|
+ */
|
|
|
|
|
+ this._useMultiview = false;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -564,6 +586,17 @@ class XRManager extends EventDispatcher {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns `true` if the engine renders to a multiview target.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return {boolean} Whether the engine renders to a multiview render target or not.
|
|
|
|
|
+ */
|
|
|
|
|
+ useMultiview() {
|
|
|
|
|
+
|
|
|
|
|
+ return this._useMultiview;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
createQuadLayer( width, height, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = [] ) {
|
|
createQuadLayer( width, height, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = [] ) {
|
|
|
|
|
|
|
|
const geometry = new PlaneGeometry( width, height );
|
|
const geometry = new PlaneGeometry( width, height );
|
|
@@ -825,6 +858,13 @@ class XRManager extends EventDispatcher {
|
|
|
scaleFactor: this._framebufferScaleFactor
|
|
scaleFactor: this._framebufferScaleFactor
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ if ( this._useMultiviewIfPossible && renderer.hasFeature( 'OVR_multiview2' ) ) {
|
|
|
|
|
+
|
|
|
|
|
+ projectionlayerInit.textureType = 'texture-array';
|
|
|
|
|
+ this._useMultiview = true;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const glBinding = new XRWebGLBinding( session, gl );
|
|
const glBinding = new XRWebGLBinding( session, gl );
|
|
|
const glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
|
|
const glProjLayer = glBinding.createProjectionLayer( projectionlayerInit );
|
|
|
const layersArray = [ glProjLayer ];
|
|
const layersArray = [ glProjLayer ];
|
|
@@ -835,6 +875,20 @@ class XRManager extends EventDispatcher {
|
|
|
renderer.setPixelRatio( 1 );
|
|
renderer.setPixelRatio( 1 );
|
|
|
renderer.setSize( glProjLayer.textureWidth, glProjLayer.textureHeight, false );
|
|
renderer.setSize( glProjLayer.textureWidth, glProjLayer.textureHeight, false );
|
|
|
|
|
|
|
|
|
|
+ let depthTexture;
|
|
|
|
|
+ if ( this._useMultiview ) {
|
|
|
|
|
+
|
|
|
|
|
+ depthTexture = new DepthArrayTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, 2 );
|
|
|
|
|
+ depthTexture.type = depthType;
|
|
|
|
|
+ depthTexture.format = depthFormat;
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+
|
|
|
|
|
+ depthTexture = new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
this._xrRenderTarget = new XRRenderTarget(
|
|
this._xrRenderTarget = new XRRenderTarget(
|
|
|
glProjLayer.textureWidth,
|
|
glProjLayer.textureWidth,
|
|
|
glProjLayer.textureHeight,
|
|
glProjLayer.textureHeight,
|
|
@@ -842,17 +896,22 @@ class XRManager extends EventDispatcher {
|
|
|
format: RGBAFormat,
|
|
format: RGBAFormat,
|
|
|
type: UnsignedByteType,
|
|
type: UnsignedByteType,
|
|
|
colorSpace: renderer.outputColorSpace,
|
|
colorSpace: renderer.outputColorSpace,
|
|
|
- depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),
|
|
|
|
|
|
|
+ depthTexture: depthTexture,
|
|
|
stencilBuffer: renderer.stencil,
|
|
stencilBuffer: renderer.stencil,
|
|
|
samples: attributes.antialias ? 4 : 0,
|
|
samples: attributes.antialias ? 4 : 0,
|
|
|
resolveDepthBuffer: ( glProjLayer.ignoreDepthValues === false ),
|
|
resolveDepthBuffer: ( glProjLayer.ignoreDepthValues === false ),
|
|
|
resolveStencilBuffer: ( glProjLayer.ignoreDepthValues === false ),
|
|
resolveStencilBuffer: ( glProjLayer.ignoreDepthValues === false ),
|
|
|
|
|
+ depth: this._useMultiview ? 2 : 1,
|
|
|
|
|
+ multiview: this._useMultiview
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
this._xrRenderTarget.hasExternalTextures = true;
|
|
this._xrRenderTarget.hasExternalTextures = true;
|
|
|
|
|
+ this._xrRenderTarget.depth = this._useMultiview ? 2 : 1;
|
|
|
|
|
|
|
|
this._supportsLayers = session.enabledFeatures.includes( 'layers' );
|
|
this._supportsLayers = session.enabledFeatures.includes( 'layers' );
|
|
|
|
|
|
|
|
|
|
+ this._referenceSpace = await session.requestReferenceSpace( this.getReferenceSpaceType() );
|
|
|
|
|
+
|
|
|
if ( this._supportsLayers ) {
|
|
if ( this._supportsLayers ) {
|
|
|
|
|
|
|
|
// switch layers to native
|
|
// switch layers to native
|
|
@@ -908,14 +967,14 @@ class XRManager extends EventDispatcher {
|
|
|
}
|
|
}
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
|
|
+ this._referenceSpace = await session.requestReferenceSpace( this.getReferenceSpaceType() );
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
this.setFoveation( this.getFoveation() );
|
|
this.setFoveation( this.getFoveation() );
|
|
|
|
|
|
|
|
- this._referenceSpace = await session.requestReferenceSpace( this.getReferenceSpaceType() );
|
|
|
|
|
-
|
|
|
|
|
renderer._animation.setAnimationLoop( this._onAnimationFrame );
|
|
renderer._animation.setAnimationLoop( this._onAnimationFrame );
|
|
|
renderer._animation.setContext( session );
|
|
renderer._animation.setContext( session );
|
|
|
renderer._animation.start();
|
|
renderer._animation.start();
|
|
@@ -950,6 +1009,7 @@ class XRManager extends EventDispatcher {
|
|
|
|
|
|
|
|
cameraXR.near = cameraR.near = cameraL.near = depthNear;
|
|
cameraXR.near = cameraR.near = cameraL.near = depthNear;
|
|
|
cameraXR.far = cameraR.far = cameraL.far = depthFar;
|
|
cameraXR.far = cameraR.far = cameraL.far = depthFar;
|
|
|
|
|
+ cameraXR.isMultiViewCamera = this._useMultiview;
|
|
|
|
|
|
|
|
if ( this._currentDepthNear !== cameraXR.near || this._currentDepthFar !== cameraXR.far ) {
|
|
if ( this._currentDepthNear !== cameraXR.near || this._currentDepthFar !== cameraXR.far ) {
|
|
|
|
|
|
|
@@ -1261,6 +1321,7 @@ function onSessionEnd() {
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
this.isPresenting = false;
|
|
this.isPresenting = false;
|
|
|
|
|
+ this._useMultiview = false;
|
|
|
|
|
|
|
|
renderer._animation.stop();
|
|
renderer._animation.stop();
|
|
|
|
|
|
|
@@ -1431,7 +1492,7 @@ function onAnimationFrame( time, frame ) {
|
|
|
backend.setXRRenderTargetTextures(
|
|
backend.setXRRenderTargetTextures(
|
|
|
this._xrRenderTarget,
|
|
this._xrRenderTarget,
|
|
|
glSubImage.colorTexture,
|
|
glSubImage.colorTexture,
|
|
|
- this._glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture
|
|
|
|
|
|
|
+ ( this._glProjLayer.ignoreDepthValues && ! this._useMultiview ) ? undefined : glSubImage.depthStencilTexture
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
}
|
|
}
|