@@ -26,8 +26,6 @@ export const WebXRControls = ({
2626 events,
2727 } = useThree ( ) ;
2828
29- const viewRef = React . useRef < XRView > ( undefined ) ;
30-
3129 // let webXR control the render loop
3230 // ie: do nothing on react-three-fiber render loop
3331 useFrame ( ( ) => {
@@ -37,17 +35,39 @@ export const WebXRControls = ({
3735 React . useLayoutEffect ( ( ) => {
3836 const gl = renderer . getContext ( ) ;
3937
38+ const originalRenderTarget = renderer . getRenderTarget ( ) ;
39+
40+ //
41+ // create the XRWebGLLayer, bind three render target to it
4042 gl . makeXRCompatible ( )
41- . then ( ( ) =>
42- webXRSession . updateRenderState ( {
43- baseLayer : new XRWebGLLayer ( webXRSession , gl ) ,
44- } )
45- )
46- . then ( ( ) => console . log ( "updateRenderState done" ) )
43+ . then ( ( ) => {
44+ const baseLayer = new XRWebGLLayer ( webXRSession , gl ) ;
45+
46+ const newRenderTarget = new THREE . WebGLRenderTarget (
47+ baseLayer . framebufferWidth ,
48+ baseLayer . framebufferHeight ,
49+ {
50+ format : THREE . RGBAFormat ,
51+ type : THREE . UnsignedByteType ,
52+ colorSpace : renderer . outputColorSpace ,
53+ stencilBuffer : gl . getContextAttributes ( ) ?. stencil ,
54+ }
55+ ) ;
56+
57+ // @ts -ignore
58+ renderer . setRenderTargetFramebuffer (
59+ newRenderTarget ,
60+ baseLayer . framebuffer
61+ ) ;
62+ renderer . setRenderTarget ( newRenderTarget ) ;
63+
64+ return webXRSession . updateRenderState ( { baseLayer } ) ;
65+ } )
4766 . catch ( setError ) ;
4867
68+ //
69+ // ask webXR for a local reference, (which we can then use to have the camera transform)
4970 let localReference : XRReferenceSpace ;
50-
5171 webXRSession
5272 . requestReferenceSpace ( "local-floor" )
5373 . then ( ( r ) => {
@@ -62,47 +82,25 @@ export const WebXRControls = ({
6282
6383 let cancelAnimationFrame : number ;
6484 let lastTimestampMs : number ;
65- let origin : THREE . Vector3 | undefined ;
6685 let renderCount = 0 ;
86+ let poseFound = false ;
6787
6888 const onXRFrame : XRFrameRequestCallback = ( timestampMs , frame ) => {
6989 const pose = localReference && frame . getViewerPose ( localReference ) ;
7090
7191 const view = pose ?. views [ 0 ] ;
92+ const glLayer = webXRSession . renderState . baseLayer ;
7293
73- if ( view ) {
74- if ( ! viewRef . current ) {
75- const glLayer = webXRSession . renderState . baseLayer ! ;
76-
77- const newRenderTarget = new THREE . WebGLRenderTarget (
78- glLayer . framebufferWidth ,
79- glLayer . framebufferHeight ,
80- {
81- format : THREE . RGBAFormat ,
82- type : THREE . UnsignedByteType ,
83- colorSpace : renderer . outputColorSpace ,
84- stencilBuffer : gl . getContextAttributes ( ) ?. stencil ,
85- }
86- ) ;
87-
88- // @ts -ignore
89- renderer . setRenderTargetFramebuffer (
90- newRenderTarget ,
91- glLayer . framebuffer
92- ) ;
93- renderer . setRenderTarget ( newRenderTarget ) ;
94-
95- const viewport = glLayer . getViewport ( view ) ! ;
96-
97- renderer . setViewport (
98- viewport . x ,
99- viewport . y ,
100- viewport . width ,
101- viewport . height
102- ) ;
103-
104- viewRef . current = view ;
105- }
94+ // check view exist (ie: tracking is ready)
95+ if ( view && glLayer ) {
96+ const viewport = glLayer . getViewport ( view ) ! ;
97+
98+ renderer . setViewport (
99+ viewport . x ,
100+ viewport . y ,
101+ viewport . width ,
102+ viewport . height
103+ ) ;
106104
107105 camera . position . set (
108106 view . transform . position . x * worldSize ,
@@ -122,22 +120,9 @@ export const WebXRControls = ({
122120
123121 camera . matrixWorldNeedsUpdate = true ;
124122
125- if ( ! origin ) {
126- // define origin,
127- // a point on the ground
128- const v = new THREE . Vector3 ( 0 , 0 , - 1 ) ;
129- v . applyQuaternion ( camera . quaternion ) ;
130- v . normalize ( ) ;
131-
132- const t = - camera . position . y / v . y ;
133-
134- if ( t > 0 ) {
135- origin = new THREE . Vector3 ( )
136- . copy ( camera . position )
137- . addScaledVector ( v , t ) ;
138-
139- onPoseFound ?.( ) ;
140- }
123+ if ( ! poseFound ) {
124+ onPoseFound ?.( ) ;
125+ poseFound = true ;
141126 }
142127
143128 const dt = ( timestampMs - ( lastTimestampMs ?? timestampMs ) ) / 1000 ;
@@ -160,11 +145,12 @@ export const WebXRControls = ({
160145 cancelAnimationFrame = webXRSession . requestAnimationFrame ( onXRFrame ) ;
161146 setFrameloop ( "never" ) ;
162147
163- // the renderer.domElement is no longer receiving events
148+ // the renderer.domElement is no longer receiving events,
149+ // connect to window instead
164150 events . connect ?.( window ) ;
165151
166152 return ( ) => {
167- // TODO: reset the framebuffer
153+ renderer . setRenderTarget ( originalRenderTarget ) ;
168154
169155 setFrameloop ( "always" ) ;
170156 webXRSession . cancelAnimationFrame ( cancelAnimationFrame ) ;
0 commit comments