Remove the lighting off a glb/gltf model after use

Hello ThreeJS Forum,

I’m seeking advice on how to remove the spotlight effect caused by a glb model. Currently, I have a button that showcases the model by adding ambient and directional lighting to highlight certain areas while rotating. However, when I stop showcasing the model, the lighting persists instead of reverting to its original state. I’ve attempted to traverse through the scene and remove the added light, but this approach hasn’t been successful. Does anyone have insights or solutions to this issue? Any help would be greatly appreciated.

Can you paste the code you’re using to remove the light?

Should be something like:

let remove = []
glbScene.traverse(e=>e.isLight&&remove.push(e));
remove.forEach(light=>light.parent.remove(light);

This is my code:

if (model) {
    model.traverse((object) => {
      if (object.isLight) {
        // Remove the light from its parent
        object.parent.remove(object);
      }
    });
  }

but it does not affect the model. When I tried yours it made the model completely black so the original color was not there.

@Fizzy have you tried removing from the scene exactly what you added, without even traversing the scene?

Something like this within some certain events:

scene.add( ambientLight );
scene.add( directionalLight );
scene.add( spotLight );
scene.remove( ambientLight );
scene.remove( directionalLight );
scene.remove( spotLight );

The thing is I have it like this.

const { camera, scene, gl } = useThree();
const [spotlightOn, setSpotlightOn] = useState(false);
scene.add( ambientLight );
scene.add( directionalLight );

//Spotlight function
const showcase = Spotlight(scene, camera, gl); //In here is where the lighting gets manipulated.
const showcaseButton= () => {
    if (showcase) {
      if (spotlightOn) {
        showcase.stop() //This should have removed all the lighting because I have scene.remove all the lughting before retuning.
      } else {
        showcase.start()
      }
      setSpotlightOn((prev) => !prev);
    }
  };

So I have implemented that method.

you should never call .add or .remove, you can pretend these functions don’t exist. you add lights, meshes and so on declaratively, and that’s how you control if they’re on, off or mounted or unmounted. you don’t alter the scene imperatively, you shouldn’t traverse.

mounting or not mounting a light is as simple as this:

const [showcaseIsOn, setShowcase] = useState(false)
...
{showcaseIsOn && <spotLight ... />}

or more performant

...
<spotLight intensity={showcaseIsOn ? 1 : 0} ... />

in react your view is the deterministic outcome of a function, it frees you from mutation, traversal and all this vanilla chaos which ends up in spaghetti code and race conditions, and this is what i’m guessing you have. it would be better not to mix the old way with the new, or you’ll just invite all the chaos back.

Thank you, removing the intensity worked.

1 Like