Video wird geladen...
Video konnte nicht geladen werden
Working on sparse volumetric light maps for WebGPU. Got generation part sorted. The resolution is adaptive, refining near geometry and skipping through most of the empty space. The video is question uses a map that's only 10MB in size, including everything. That's less the amount of GPU memory that... show more
18,702 Aufrufe • vor 9 Monaten •via X (Twitter)
17 Kommentare

you can do visualization via sdf repetition. Treat your sparse volumetric data like a TLAS.

That's a pretty cool idea, thanks! I just reached for the tool available, but yeah, I was wondering how to visualize 1M+ probes eventually

super cool, ought to do something like this

It reminds me of the Sparse Irradiance Volunes of Assassin’s Creed Origins and later games

That's cool but I wouldn't call this a lightmap. These are light probes. Lightmaps are usually 2d maps.

You're right, it's a bit of a misnomer. I'm borrowing Unreal's terminology on this calling it "light map". Typically you'd call it a "volume" instead of a map. But "volumetric lightmap" also makes sense to me. Terminology in the space of GPU techniques is all over the place

Have you tried any method that spawns cache entries from G-buffer hits, rather than pre-populating it everywhere in space?

Actually yes! Played with this idea with SHaRC, the results were okay, but you're missing a lot of the signal due to angular cutoff from occlusion. Compensating for this is the real challenge, when you move the camera - you want to keep that accumulated result, while filling in missing angular contribution. I think it can work, with octahedral probes, where you clearly discretize contribution by angle

it does not look sparse to me

And yet it's only about 4% the size of the dense grid of the same resolution :P

How many texture reads and indirections do you have per pixel for one sample?

No texture reads, it's all just buffer data. There's 1 buffer, a metadata header followed by a flat `array<u32>`. It's a recursive structure, so the final number of reads depends on the depth. Typically it's within 4 levels as that gets you to ~1024x1024x1024 equivalent dense grid resolution. I use the standard tricks to speed up memory access. The tree nodes are laid out in memory using a hamilton curve and probes are packed into a continuous region at the end of the buffer. There are 2 indirections: 1. Node children are referenced via pointers (index into the buffer) 2. Probes of each node are referenced via pointers I believe a technique like Unreal's where the grid is basically an inverted MIP pyramid is going to be faster in terms of access. I'm having to do software trilinear filtering, and there is the indirection you mentioned. Can't say how much of an impact this will have in the end though, as this is still WiP and I'm yet to do benchmarks

@guycalledfrank I think the question was... How do you use it when rendering? Do you sample nearest or linear etc...

@guycalledfrank Sure, it's linear, we want lighting to be C0 continuous at least.

How do you encode the lighting data in each probe, SH? And is there visibility information as well?

second order SH, that's 9 coefficients. Only irradiance. RGBE9995 encoding, so a total of 36 bytes per probe. No visibility. Light leakage can be an issue, but likely not a huge one, as resolution increases close to geometry, so probe density is quite high. For example, a volume restricted to ~30Mb has ~720,000 probes. That's a lot of probes :)

Gotcha, IIRC nvidia did press on the importance of visibility data for better filtering and occlusion information. Guess it is all a performance to quality ratio
