From 62b5fff74d0bd7a96bcdbbbc2369f27fef4b006d Mon Sep 17 00:00:00 2001 From: SxP Date: Fri, 23 Sep 2022 14:36:03 -0700 Subject: [PATCH 1/2] Fix WebXR Layers example. Invisible dummy meshes relied on old alphaWrite logic so they became opaque after dfca2bd4748b00245225c9e4d8ba0ef7374c9b36 on Jan 27 and obscured the quad layers. This switches to using colorWrite=false logic to properly create holes in the 3D scene and let the dummy meshes interect the controller ray without obscuring the quad layers. Tested: * https://raw.githack.com/sigmaxipi/three.js/webXrLayersFix/examples/index.html?q=webxr#webxr_vr_layers Properly shows the charts on the top two quads on a Quest 2 with chrome://flags/#webxr-layers enabled and ray intersection works properly with the quad layers and GUI. --- examples/webxr_vr_layers.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/webxr_vr_layers.html b/examples/webxr_vr_layers.html index 0ca1d7eaf998e3..650ea4edbb2037 100644 --- a/examples/webxr_vr_layers.html +++ b/examples/webxr_vr_layers.html @@ -144,6 +144,11 @@ ] ); const line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: 0x5555ff } ) ); + // It's important to have all the visible GUI elements render after the invisible quads which + // will use the default renderOrder=0. This ensures that the invisible elements obscure any + // parts of the scene to create the illusion that the XR layers rendered after the 3D scene. + line.renderOrder = 1; + const controllerModelFactory = new XRControllerModelFactory(); const handModelFactory = new XRHandModelFactory().setPath( './models/fbx/' ); @@ -202,7 +207,7 @@ // projection layer is rendered. const dummyMeshLeft = new THREE.Mesh( new THREE.PlaneGeometry( snellenConfig.widthMeters, snellenConfig.heightMeters ), - new THREE.MeshBasicMaterial( { opacity: 0 } ) ); + new THREE.MeshBasicMaterial( { colorWrite: false } ) ); dummyMeshLeft.position.x = snellenConfig.x - snellenConfig.widthMeters; dummyMeshLeft.position.y = snellenConfig.y + snellenConfig.heightMeters; eyeCharts.add( dummyMeshLeft ); @@ -255,7 +260,8 @@ guiMesh.position.set( 1.0, 1.5, - 1.0 ); guiMesh.rotation.y = - Math.PI / 4; guiMesh.scale.setScalar( 2 ); - guiMesh.material.opacity = 0; + guiMesh.material.colorWrite = false; + guiMesh.material.transparent = false; group.add( guiMesh ); // Error message if layer initialization fails. From 95dc0c8ce7a5d8d982a41b0ad20dd07e0f88d2d0 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Mon, 26 Sep 2022 10:20:00 +0200 Subject: [PATCH 2/2] Update webxr_vr_layers.html --- examples/webxr_vr_layers.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/webxr_vr_layers.html b/examples/webxr_vr_layers.html index 650ea4edbb2037..5f20da9bfd2c82 100644 --- a/examples/webxr_vr_layers.html +++ b/examples/webxr_vr_layers.html @@ -144,9 +144,8 @@ ] ); const line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: 0x5555ff } ) ); - // It's important to have all the visible GUI elements render after the invisible quads which - // will use the default renderOrder=0. This ensures that the invisible elements obscure any - // parts of the scene to create the illusion that the XR layers rendered after the 3D scene. + // The invisible dummyMesh quads and the guiMesh need to be rendered before the controller lines so that they + // leave a hole in the depth buffer that the lines can intersect. line.renderOrder = 1; const controllerModelFactory = new XRControllerModelFactory();