Skip to content

Commit

Permalink
Add XRRenderTarget. (#30369)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mugen87 authored Jan 21, 2025
1 parent f4ff275 commit 325bb90
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 15 deletions.
19 changes: 15 additions & 4 deletions src/renderers/common/Textures.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,18 @@ class Textures extends DataMap {

const options = { sampleCount };

if ( ( renderTarget.isXRRenderTarget === true && renderTarget.hasExternalTextures === true ) === false ) {
// when using the WebXR Layers API, the render target uses external textures which
// require no manual updates

if ( renderTarget.isXRRenderTarget === true && renderTarget.hasExternalTextures === true ) {

if ( depthTexture && renderTarget.autoAllocateDepthBuffer === true ) {

this.updateTexture( depthTexture, options );

}

} else {

for ( let i = 0; i < textures.length; i ++ ) {

Expand All @@ -139,11 +150,11 @@ class Textures extends DataMap {

}

}
if ( depthTexture ) {

if ( depthTexture && renderTarget.autoAllocateDepthBuffer !== false ) {
this.updateTexture( depthTexture, options );

this.updateTexture( depthTexture, options );
}

}

Expand Down
12 changes: 5 additions & 7 deletions src/renderers/common/XRManager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { EventDispatcher } from '../../core/EventDispatcher.js';
import { RenderTarget } from '../../core/RenderTarget.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
import { RAD2DEG } from '../../math/MathUtils.js';
import { Vector2 } from '../../math/Vector2.js';
Expand All @@ -9,6 +8,7 @@ import { Vector4 } from '../../math/Vector4.js';
import { WebXRController } from '../webxr/WebXRController.js';
import { DepthFormat, DepthStencilFormat, RGBAFormat, UnsignedByteType, UnsignedInt248Type, UnsignedIntType } from '../../constants.js';
import { DepthTexture } from '../../textures/DepthTexture.js';
import { XRRenderTarget } from './XRRenderTarget.js';

const _cameraLPos = /*@__PURE__*/ new Vector3();
const _cameraRPos = /*@__PURE__*/ new Vector3();
Expand Down Expand Up @@ -316,7 +316,7 @@ class XRManager extends EventDispatcher {
this._xrFrame = null;

/**
* Whether to use projection layers or not.
* Whether to use the WebXR Layers API or not.
*
* @private
* @type {Boolean}
Expand Down Expand Up @@ -624,7 +624,7 @@ class XRManager extends EventDispatcher {
renderer.setPixelRatio( 1 );
renderer.setSize( glProjLayer.textureWidth, glProjLayer.textureHeight, false );

this._xrRenderTarget = new RenderTarget(
this._xrRenderTarget = new XRRenderTarget(
glProjLayer.textureWidth,
glProjLayer.textureHeight,
{
Expand Down Expand Up @@ -657,7 +657,7 @@ class XRManager extends EventDispatcher {
renderer.setPixelRatio( 1 );
renderer.setSize( glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, false );

this._xrRenderTarget = new RenderTarget(
this._xrRenderTarget = new XRRenderTarget(
glBaseLayer.framebufferWidth,
glBaseLayer.framebufferHeight,
{
Expand All @@ -670,8 +670,6 @@ class XRManager extends EventDispatcher {

}

this._xrRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278

//

this.setFoveation( this.getFoveation() );
Expand Down Expand Up @@ -1116,7 +1114,7 @@ function onAnimationFrame( time, frame ) {
// For side-by-side projection, we only produce a single texture for both eyes.
if ( i === 0 ) {

backend.setRenderTargetTextures(
backend.setXRRenderTargetTextures(
this._xrRenderTarget,
glSubImage.colorTexture,
this._glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture
Expand Down
74 changes: 74 additions & 0 deletions src/renderers/common/XRRenderTarget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { RenderTarget } from '../../core/RenderTarget.js';

/**
* A special type of render target that is used when rendering
* with the WebXR Device API.
*
* @private
* @augments RenderTarget
*/
class XRRenderTarget extends RenderTarget {

/**
* Constructs a new XR render target.
*
* @param {Number} [width=1] - The width of the render target.
* @param {Number} [height=1] - The height of the render target.
* @param {Object} [options={}] - The configuration options.
*/
constructor( width = 1, height = 1, options = {} ) {

super( width, height, options );

/**
* This flag can be used for type testing.
*
* @type {Boolean}
* @readonly
* @default true
*/
this.isXRRenderTarget = true;

/**
* Whether the attachments of the render target
* are defined by external textures. This flag is
* set to `true` when using the WebXR Layers API.
*
* @type {Boolean}
* @default false
*/
this.hasExternalTextures = false;

/**
* Whether a depth buffer should automatically be allocated
* for this XR render target or not.
*
* Allocating a depth buffer is the default behavior of XR render
* targets. However, when using the WebXR Layers API, this flag
* must be set to `false` when the `ignoreDepthValues` property of
* the projection layers evaluates to `true`.
*
* Reference: {@link https://www.w3.org/TR/webxrlayers-1/#dom-xrprojectionlayer-ignoredepthvalues}.
*
* @type {Boolean}
* @default true
*/
this.autoAllocateDepthBuffer = true;

}

copy( source ) {

super.copy( source );

this.hasExternalTextures = source.hasExternalTextures;
this.autoAllocateDepthBuffer = source.autoAllocateDepthBuffer;

return this;

}


}

export { XRRenderTarget };
10 changes: 6 additions & 4 deletions src/renderers/webgl-fallback/WebGLBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,15 @@ class WebGLBackend extends Backend {
}

/**
* Configures the render target with external textures.
* Configures the given XR render target with external textures.
*
* @param {RenderTarget} renderTarget - The render target.
* This method is only relevant when using the WebXR Layers API.
*
* @param {XRRenderTarget} renderTarget - The XR render target.
* @param {WebGLTexture} colorTexture - A native color texture.
* @param {WebGLTexture?} [depthTexture=null] - A native depth texture.
*/
setRenderTargetTextures( renderTarget, colorTexture, depthTexture = null ) {
setXRRenderTargetTextures( renderTarget, colorTexture, depthTexture = null ) {

this.set( renderTarget.texture, { textureGPU: colorTexture } );

Expand Down Expand Up @@ -1929,7 +1931,7 @@ class WebGLBackend extends Backend {
const isRenderTarget3D = renderTarget.isRenderTarget3D === true;
const isRenderTargetArray = renderTarget.isRenderTargetArray === true;
const isXRRenderTarget = renderTarget.isXRRenderTarget === true;
const hasExternalTextures = renderTarget.hasExternalTextures === true;
const hasExternalTextures = ( isXRRenderTarget === true && renderTarget.hasExternalTextures === true );

let msaaFb = renderTargetContextData.msaaFrameBuffer;
let depthRenderbuffer = renderTargetContextData.depthRenderbuffer;
Expand Down

0 comments on commit 325bb90

Please sign in to comment.