Skip to content

WebGPURenderer: Added ClusteredLighting (Forward+ clustered) shading.#33406

Open
mrdoob wants to merge 5 commits intodevfrom
clustered
Open

WebGPURenderer: Added ClusteredLighting (Forward+ clustered) shading.#33406
mrdoob wants to merge 5 commits intodevfrom
clustered

Conversation

@mrdoob
Copy link
Copy Markdown
Owner

@mrdoob mrdoob commented Apr 17, 2026

Description

Adds a ClusteredLighting addon that partitions the view frustum into a 3D cluster grid (screen tiles × exponential depth slices). A compute pass builds a per-cluster light list via sphere-vs-AABB tests; the material-side lookup only evaluates lights that actually reach the fragment.

Defaults: 32 px tiles, 24 depth slices, 64 lights per cluster, 1024 max lights.

https://raw.githack.com/mrdoob/three.js/clustered/examples/webgpu_lights_clustered.html

@sunag Any interest on following/finishing this?

Partitions the view frustum into a 3D cluster grid (screen tiles × exponential depth slices) so each fragment only evaluates the point lights whose spheres intersect its cluster. Suitable for 3D scenes with many point lights and real depth complexity, where the existing 2D `TiledLighting` drops lights that share screen pixels at different depths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mrdoob mrdoob added this to the r185 milestone Apr 17, 2026
@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 17, 2026

What's the difference to the existing TiledLighting module?

https://threejs.org/examples/webgpu_lights_tiled

IMO, we should only provide a single Forward+ implementation otherwise it becomes confusing. We should either replace TiledLighting or enhance it with the ideas of this PR (if applicable).

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 17, 2026

I know this is work-in-progress but still did some testing on my system.

The new demo webgpu_lights_clustered runs with 9 FPS on my macMini with Chrome.

Besides, the lighting looks broken. Everything appears very blocky:

Roof:

Bildschirmfoto 2026-04-17 um 16 24 51

Floor:

Bildschirmfoto 2026-04-17 um 16 25 29

@sunag
Copy link
Copy Markdown
Collaborator

sunag commented Apr 18, 2026

What's the difference to the existing TiledLighting module?

Tiled and Clustered shading reduce the lighting processing in the fragment shader because, instead of calculating all lights in the scene, we only calculate the lights associated with a specific tile or cluster. The main difference, in short, is that tiled shading is based only on the 2d-screen dividing in tiles, while clustered also considers depth by creating z-slices, the lights matching should be more accurate for clustered for this reason.

The new demo webgpu_lights_clustered runs with 9 FPS on my macMini with Chrome.

One of the reasons for the performance issue is the light distance (range) in the example. Reducing the distance should improve it, no have sure if it is enough, but considering that we can have up to 64 lights per cluster, which is quite a lot if they are all included in the same cluster. If put the distance=1 in addLight it is possible feel the diference.

The artifacts are probably related to this as well. If we have many lights included in the same cluster, it could exceed the limits, and some lights may be missing from that cluster.

It seems there is a bug when I resize the window.

@sunag
Copy link
Copy Markdown
Collaborator

sunag commented Apr 20, 2026

IMO, we should only provide a single Forward+ implementation otherwise it becomes confusing. We should either replace TiledLighting or enhance it with the ideas of this PR (if applicable).

I think we can remove TiledLighting after merge this, we will still need to add support for SpotLight and then enumerated the non-area lights, I think we can do similar to what @RenaudRohlinger did in webgpu_lights_dynamic for DirectionalLight, AmbientLight, etc.

I improved the debug adding support for z-slice.

image

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 21, 2026

Looking great!

Unfortunately, I still have around 20 FPS on a M2 Pro. Would it be possible to half the number of point lights? I bet the example will still look good.

Also the resize does not seem to work as expected:

  • The resize talks quite long and stutters more than in most other examples.
  • Performance does not seem to improve when decreasing the window size.
  • Reloading the example with a smaller window improves the performance.

I've also noticed this error in the browser console (probably unrelated to the PR).

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants