From f54efbf73425c7e82c492d7af954d471b60a4eed Mon Sep 17 00:00:00 2001 From: Hermes Date: Tue, 4 Aug 2026 23:35:10 +0000 Subject: [PATCH] =?UTF-8?q?fix(lab):=20AR=20Passthrough=20black=20screen?= =?UTF-8?q?=20=E2=80=94=20transparent=20canvas=20+=20immersive-ar=20detect?= =?UTF-8?q?ion=20+=20dynamic=20AR=20background?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gl.alpha:true + setClearColor(0,0) no WebGL renderer - ARBackground detecta environmentBlendMode='additive' e vira transparente - Tenta navigator.xr.requestSession('immersive-ar') antes do fallback immersive-vr - local-floor required + hand-tracking/plane-detection/hit-test optional --- src/lab/QuestCubeLab.tsx | 72 +++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/src/lab/QuestCubeLab.tsx b/src/lab/QuestCubeLab.tsx index d5f7076..da535f7 100644 --- a/src/lab/QuestCubeLab.tsx +++ b/src/lab/QuestCubeLab.tsx @@ -316,10 +316,11 @@ const PhysicsScene = ({ // =================================================================== const SceneContent = ({ locked, resetSignal }: { locked: boolean; resetSignal: number }) => ( <> - - - - + {/* Em modo AR Passthrough, NÃO pinta cor de fundo — ela veda o passthrough */} + {/* Em modo desktop (fora do XR), pinta fundo escuro pra não ficar transparente estranho */} + + + - {/* Grid estilo HLA */} + {/* Grid estilo HLA — funciona em ambos os modos */} ); +// =================================================================== +// FUNDO DINÂMICO — VR imersivo fica preto; AR Passthrough fica transparente +// =================================================================== +const ARBackground = () => { + const session = useXR((s) => s.session); + const isAR = session && "environmentBlendMode" in session && (session as any).environmentBlendMode === "additive"; + if (isAR) return null; // AR = transparente (mostra passthrough do Quest 3) + return ( + <> + + + + ); +}; + // =================================================================== // JOYSTICK HANDLER — gamepad pro controle fora do XR // =================================================================== @@ -410,7 +426,39 @@ export default function QuestCubeLab() { useEffect(() => { if (autoEnter) { - store.enterXR?.().catch(() => {}); + // Meta Quest 3 suporta immersive-ar (Passthrough AR). Tenta primeiro. + // Fallback pra immersive-vr se AR não disponível (óculos sem passthrough). + (async () => { + try { + if ('xr' in navigator) { + const xr = (navigator as any).xr; + const supported: boolean = await xr.isSessionSupported('immersive-ar').catch(() => false); + if (supported) { + const sessionInit: XRSessionInit = { + requiredFeatures: ['local-floor'], + optionalFeatures: ['hand-tracking', 'plane-detection', 'hit-test'], + }; + await xr.requestSession('immersive-ar', sessionInit); + return; + } + } + // Fallback: usa o XR controller padrão do store + const ctrl: any = store as any; + const enterFn = ctrl.enterAR || ctrl.enterVR || ctrl.enterXR; + try { + await enterFn.call(ctrl, 'immersive-vr' as any); + } catch { + // ignore + } + } catch { + // qualquer erro, tenta o enter padrão + try { + await Promise.resolve(store.enterXR?.()); + } catch { + // ignore + } + } + })(); } }, [autoEnter]); @@ -473,9 +521,17 @@ export default function QuestCubeLab() { Rapier Physics ativo • Half-Life: Alyx-like - {/* Canvas com XR */} + {/* Canvas com XR — gl.alpha:true permite passthrough por trás */} - + { + gl.setClearColor(0x000000, 0); // transparente + gl.xr.enabled = true; + }} + >