playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
https://playcanvas.com
MIT License
9.59k stars 1.34k forks source link

Implement clustered lighting as a main lighting system (Root ticket) #3522

Open mvaligursky opened 3 years ago

mvaligursky commented 3 years ago

This is the issue to track progress for the clustered lighting implementation in the engine. Here are the most important steps:

Optional features:

Other related PRs

Public release after rounds of beta testing: https://github.com/playcanvas/engine/pull/4586

Maksims commented 3 years ago

One major issue for forward-renderer approach to lights is that light-related shader code is added to materials, and one huge bottleneck with this approach is when enabling/disabling lights - leads to all affected materials shader revalidation and recompilation, which is extremely slow.

I guess with shadow atlas and clustered version, this will not be an issue anymore?

mvaligursky commented 3 years ago

That's correct, adding / removing lights will not rebuild the shaders when fully integrated (it does currently). And also you only pay for the lights that are "nearby" instead of all, for both static and dynamic lights.

Maksims commented 2 years ago

Currently, when creating lights with shadows using atlases, with profiler engine, it does not add/remove VRAM usage from for app.stats.vram.texShadow.

Also, adding new lights, it seems to generate new materials, but might not be removing old ones. app.stats.shaders.materialShaders.

mvaligursky commented 2 years ago

Currently, when creating lights with shadows using atlases, with profiler engine, it does not add/remove VRAM usage from for app.stats.vram.texShadow

I added console.log(app.stats.vram.texShadow); to clustered-spot-shadows example update loop .. and when I change the shadow atlas resolution using the slider, it updates the allocated size. How do you reproduce the issue? Internally, a normal shadow map is allocated, and that already works .. so this works as well.

Note that only a single atlas is used .. there is no per-light allocation taking place. If you set atlas to be 4k x 4k, it allocates it ones and then just subdivides for the visible lights that need shadows during the frame.

Also, adding new lights, it seems to generate new materials, but might not be removing old ones

I think engine keeps all shaders around to avoid compilation should the same shader be needed at a later stage. When clustered lights are fully integrated, it will not create new shaders when lights are added though, this has not been done.