11import * as THREE from 'three' ;
22import * as xb from 'xrblocks' ;
33
4- import { SegmenterController } from './SegmenterController.js' ;
5-
64// Backdrop modes for the cut-out background.
75// 0 = passthrough: background pixels are discarded so you see straight
86// through the window to the real world behind it.
@@ -77,9 +75,10 @@ const FRAGMENT_SHADER = /* glsl */ `
7775 // The camera texture uses GL flipY; the mask DataTexture does not, so
7876 // flip the mask's v to line the two up.
7977 float id = texture2D(uMask, vec2(vUv.x, 1.0 - vUv.y)).r * 255.0;
80- // Until the first mask arrives, show the raw feed. Category 0 is the
81- // background; everything else is a person.
82- bool isPerson = (uHasMask < 0.5) || (id >= 0.5);
78+ // Until the first mask arrives, treat the whole frame as background so we
79+ // show the backdrop rather than flashing the raw camera (the room) during
80+ // model warm-up. Category 0 is background; everything else is a person.
81+ bool isPerson = (uHasMask > 0.5) && (id > 0.5);
8382 if (isPerson) {
8483 gl_FragColor = vec4(cam, 1.0);
8584 return;
@@ -95,7 +94,6 @@ const FRAGMENT_SHADER = /* glsl */ `
9594export class MagicWindow extends xb . Script {
9695 constructor ( ) {
9796 super ( ) ;
98- this . segmenter = new SegmenterController ( ) ;
9997 this . frameCanvas = document . createElement ( 'canvas' ) ;
10098 this . frameCtx = this . frameCanvas . getContext ( '2d' , {
10199 willReadFrequently : true ,
@@ -145,8 +143,6 @@ export class MagicWindow extends xb.Script {
145143 this . plane . position . set ( 0 , 1.5 , - 1.2 ) ;
146144 this . add ( this . plane ) ;
147145
148- this . segmenter . load ( ) ;
149-
150146 // Quick keyboard control until the spatial panel lands: B cycles backdrop.
151147 this . onKeyDown_ = ( event ) => {
152148 if ( event . key === 'b' || event . key === 'B' ) {
@@ -250,10 +246,14 @@ export class MagicWindow extends xb.Script {
250246 }
251247
252248 updateMask_ ( ) {
253- if ( ! this . segmenter . isReady ) {
249+ // The Segmenter's own update() loop keeps latestMask fresh at its
250+ // configured cadence. Reading it here is a synchronous poll — no
251+ // MediaPipe inference is triggered by this call.
252+ const segmentation = xb . core . world ?. segmentation ;
253+ if ( ! segmentation ) {
254254 return ;
255255 }
256- const mask = this . segmenter . segment ( this . frameCanvas ) ;
256+ const mask = segmentation . latestMask ;
257257 if ( ! mask ) {
258258 return ;
259259 }
@@ -283,7 +283,6 @@ export class MagicWindow extends xb.Script {
283283
284284 dispose ( ) {
285285 window . removeEventListener ( 'keydown' , this . onKeyDown_ ) ;
286- this . segmenter . dispose ( ) ;
287286 this . cameraTexture ?. dispose ( ) ;
288287 this . maskTexture ?. dispose ( ) ;
289288 this . plane . geometry . dispose ( ) ;
0 commit comments