WebGPU Lighting Issue - Unable to Dynamically Add or Remove Lights

Hi everyone, I’m encountering a problem with WebGPU in Three.js (version 171). When I try to dynamically add or remove lights in the scene, the changes are reflected in the scene.children when I inspect it, but they have no visible effect on the rendered canvas. Lights only seem to work correctly when initialized. Below is the core code:


function initLights() {
  const light = new THREE.DirectionalLight(0xddffdd, 3);
  light.name = "DirectionalLight";
  const randomPosition = () => Math.random() * 5 - 2.5;
  light.position.set(randomPosition(), randomPosition(), randomPosition());
  state.scene.add(light);

  const lightHelper = new THREE.DirectionalLightHelper(light, 1);
  lightHelper.name = "DirectionalLightHelper";
  state.scene.add(lightHelper);
}

function addLight() {
  const existingLights = state.scene.children.filter(child => child.name === "DirectionalLight");
  if (existingLights.length >= 5) {
    return;
  }
  initLights();
}

function removeLight() {
  const light = state.scene.getObjectByName("DirectionalLight");
  const lightHelper = state.scene.getObjectByName("DirectionalLightHelper");

  [light, lightHelper].forEach(obj => {
    if (obj) {
      state.scene.remove(obj);
      obj.dispose();
    }
  });
}

Problem Details:

  1. Lights initialized with initLights() at the beginning work as expected.

  2. Clicking to dynamically add or remove lights updates the scene (confirmed via inspecting scene.children), but there are no visible changes in the WebGPU-rendered canvas.

  3. This issue only occurs with WebGPU. Switching to WebGL resolves the issue.

Questions:

• Is this a limitation or a bug in WebGPU support for Three.js (version 171)?

• Do I need to explicitly update the renderer or scene after adding/removing lights?

• Has anyone encountered similar issues or knows a workaround for dynamically managing lights with WebGPU?

Reminded about this topic: Adding and removing three.js lights at run time - #6 by Mugen87

Thank you for your reply! I’ve checked the post you mentioned, but unfortunately, it didn’t solve my issue.

I tried the following code to update all materials after removing the lights:

state.scene.traverse((object) => {
  if (object instanceof THREE.Mesh) {
    if (object.material instanceof THREE.MeshStandardMaterial) {
      object.material.needsUpdate = true;
    }
  }
});

However, this didn’t have any effect. The issue persists when using the WebGPU renderer. Once I switch back to WebGL, everything works perfectly, including the ability to add and remove lights dynamically.

Do you know how to completely remove lights in a WebGPU environment? Is there any additional step required to update the renderer or scene after modifying the lights?

Here is a standalone HTML file that you can try:

WebGPU Lights.zip (1.6 KB)

The way you are importing WebGPU seems to be incorrect as well as material parameters.
I did also add some small code changes.

@GitHubDragonFly Thank you for your response! I reviewed your code, and it indeed works for rendering correctly. However, it doesn’t address my specific need, and I realize I might not have described my issue clearly enough.

What I need is to dynamically add and remove lights in the scene. Currently, this functionality is not working as expected. I tried modifying your code to achieve this, but unfortunately, I couldn’t get it to work. When I call add or remove, the scene visually doesn’t reflect any changes, even though the scene’s object structure updates as expected.

Here’s the modified version of your code that I attempted:

WebGPU Lights.zip (2.1 KB)

Despite these updates, the scene remains visually unchanged after adding or removing lights. Could you help me identify why the scene doesn’t update when I dynamically modify the lights? I’d really appreciate your help!

I don’t really know but that functionality currently does not seem present in the WebGPU renderer.

Only somebody who knows WebGPU code well could properly answer:

  • why this is not working
  • whether it’s planned to be included in the future
  • whether we are using a wrong approach
  • whether we are making a mistake by expecting everything to work

Try to stick with what works properly.

@GitHubDragonFly Thank you for your input!
I understand that the WebGPU renderer is still under development and may not fully support all functionalities yet. My main concern is whether this is a limitation of the current WebGPU implementation or if I’m approaching it incorrectly.

My comment from 2018 about adding/removing lights does not reflect how recent three.js versions work. In WebGLRenderer, adding and removing lights does not require a manual needsUpdate=true for all materials in the scene anymore since the change of the lighting state is automatically detected by the renderer, see: three.js dev template - module - JSFiddle - Code Playground

In WebGPURenderer this bit is currently missing: three.js dev template - module - JSFiddle - Code Playground

@Zhi_She Would you mind filing an issue at GitHub for that?

3 Likes

Thank you for pointing this out!

I’ve submitted an issue on GitHub as you suggested: #30044 - WebGPURenderer does not detect dynamic light addition/removal.

Thanks again for your guidance and support!

1 Like

The issue has been fixed via:

Will be available with r172.

3 Likes