Hey guys,
I’ve been working on a forward+ renderer for a while and wanted to show off a little the results so far.
The scene is recognizable Sponza with 1000 moving point lights.
Controls
The navigation is via mouse, it’s the standard OrbitControls
. So left mouse drag to look around and right mouse to pan, wheel to zoom in/out. There are also 3 interactable things on the screen, buttons in the bottom left that toggle different render layers. Of interest there are 2 and 3 that contain most of the scene, 2 contains debug material that shows heatmap of number of lights in each cluster.
Top left left corner contains toggle for 2d debugger that shows cluster light counts.
Finally, bottom right corner contains rendering of cluster texture itself.
Motivation
There have been quite a few tiled and even clustered renderer projects in the past, but they all have various limitations, like maximum number of lights per cluster/tile or hard limit on number of lights. My approach follows a more flexible approach with a 3d texture encoding clusters and 2 levels of de-referencing to keep memory requirement of this solution down.
I’m trying to build an extension to WebGLRenderer
that would just work out of the box with existing materials in three.js
. I tried going down the deferrer rendering path, but three.js doesn’t support multiple render targets currently, so that’s a no-go. Forward+ is the only logical alternative. Tiled forward+ example was a great starting point, having clusters adds another dimension for culling, which is just a logical extension. My implementation is fully configurable in clustering resolution, the example linked here uses 24x12x12 resolution, that is a total of 3456 unique “clusters” in the scene.
Optimizations
One major difference is also to do with precise frustum/sphere intersection testing. That one took a couple of days to fully figure out. What this means is that my implementation does not have false-positives. Pretty much every other clustered renderer is satisfied with the standard aabb/frustum intersection test that over estimates bounds of the sphere by around ~47.6% from the outset as well producing a massive number of false-positives per cluster because of inherent fault in multi-plane intersection test.
References
Here are some links I found very useful during my research in no particular order:
Show
- http://www.humus.name/Articles/PracticalClusteredShading.pdf
- Forward vs Deferred vs Forward+ Rendering with DirectX 11 | 3D Game Engine Programming
- http://www.cse.chalmers.se/~uffe/clustered_shading_preprint.pdf
- graphics-snippets/model_view_projection_depth.md at a34eb2d99a2bb6453651865a7f0ea633f8edd06e · Rabbid76/graphics-snippets · GitHub
- Three Methods to Extract Frustum Points · Gazoo.vrv
- GitHub - illDivino/Project5-WebGL-Clustered-Deferred-Forward-Plus
- GitHub - LanLou123/WebGL-Clustered-Deferred-Forward-Plus-Rendering: webGL implementation of dense light scene, included deferred & clustered rendering for accelaration
- Simple Alternative to Clustered Shading for Thousands of Lights – World Of Fries
- WebGL2 What's New