From 0a9035257f67aec04444c8a0a286e2cb0068b998 Mon Sep 17 00:00:00 2001 From: Daniel Rossi Date: Wed, 30 Apr 2025 23:18:19 +1000 Subject: [PATCH 01/19] Adding native media layer creation for WebGPU XR. This fixes a context loss issue doing it outside the manager. #31029 --- examples/webgpu_xr_media_layer.html | 191 ++++++++++++++++++++++++++++ src/renderers/common/XRManager.js | 58 ++++++++- 2 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 examples/webgpu_xr_media_layer.html diff --git a/examples/webgpu_xr_media_layer.html b/examples/webgpu_xr_media_layer.html new file mode 100644 index 00000000000000..b1935726a49ca1 --- /dev/null +++ b/examples/webgpu_xr_media_layer.html @@ -0,0 +1,191 @@ + + + + three.js vr - 360 stereo video + + + + + +
+ +
+ three.js vr - 360 stereo video native media layers
+ stereoscopic panoramic render by pedrofe. scene from mery project. +
+ + + + + + + + + + + + diff --git a/src/renderers/common/XRManager.js b/src/renderers/common/XRManager.js index 7c644505aaf5d3..3bfc4ca82f9226 100644 --- a/src/renderers/common/XRManager.js +++ b/src/renderers/common/XRManager.js @@ -375,6 +375,16 @@ class XRManager extends EventDispatcher { */ this._useMultiview = false; + /** + * Stores params and video elements for equirect layers + */ + this._mediaLayers = []; + + /** + * Stores the created equrect layers for updating render state + */ + this._createdMediaLayers = []; + } /** @@ -594,6 +604,31 @@ class XRManager extends EventDispatcher { return this._useMultiview; + } + + /** + * Sets up params for an equirect native video layer. + * @param {*} video The video element + * @param {*} layout The layout to use either mono/stereo-left-right/stereo-top-bottom + * @param {*} transform A transform param for the layer + * @param {*} is180 If it's a 180 video + * @param {*} params Extra params for the layer to add but not needed. + */ + createMediaLayer(video, layout = "mono", transform = {}, is180 = false, params = {}) { + const angleFactor = is180 ? 1 : 2; + + this._mediaLayers.push({ + video: video, + params: { + layout: layout, + centralHorizontalAngle: Math.PI * angleFactor, + transform: new XRRigidTransform( + {}, + transform + ), + ...params + } + }); } createQuadLayer( width, height, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = [] ) { @@ -657,7 +692,7 @@ class XRManager extends EventDispatcher { const xrlayers = this._session.renderState.layers; xrlayers.unshift( layer.xrlayer ); - this._session.updateRenderState( { layers: xrlayers } ); + this._session.updateRenderState( { layers: [...this._createdMediaLayers, ...xrlayers] } ); } else { @@ -731,7 +766,7 @@ class XRManager extends EventDispatcher { const xrlayers = this._session.renderState.layers; xrlayers.unshift( layer.xrlayer ); - this._session.updateRenderState( { layers: xrlayers } ); + this._session.updateRenderState( { layers: [...this._createdMediaLayers, ...xrlayers] } ); } else { @@ -918,9 +953,26 @@ class XRManager extends EventDispatcher { } + //Creates the equirect media layers on session creation + if (this._mediaLayers.length) { + + const mediaBinding = new XRMediaBinding( session ); + + this._createdMediaLayers = this._mediaLayers.map(layer => { + return mediaBinding.createEquirectLayer( + layer.video, + { + space: this._referenceSpace, + ...layer.params + } + ); + }); + } + + } - session.updateRenderState( { layers: layersArray } ); + session.updateRenderState( { layers: [...this._createdMediaLayers, ...layersArray] } ); } else { From 9059ba2c0b9c97ffce8736c0cfcb61e1acefc9dd Mon Sep 17 00:00:00 2001 From: Daniel Rossi Date: Wed, 30 Apr 2025 23:23:08 +1000 Subject: [PATCH 02/19] cleanup example --- examples/webgpu_xr_media_layer.html | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/webgpu_xr_media_layer.html b/examples/webgpu_xr_media_layer.html index b1935726a49ca1..fa15c96d3cbe61 100644 --- a/examples/webgpu_xr_media_layer.html +++ b/examples/webgpu_xr_media_layer.html @@ -18,12 +18,6 @@ - - - -