Strolle: pretty lightning, 🌈 global illumination 🌈, 6D hashmaps, progress report with a dungeon scene!

130 points Patryk27

Strolle is a real-time rendering engine that uses ray-tracing to achieve aesthetic lightning effects such as 🌈 global illumination 🌈:

\(you might wanna bump your screen's backlight a bit to see all of the effects\)

tl;dr GI is when you simulate how light bounces around a scene before it it seen by the camera - on the screenshot above it is apparent in two places:

\- the floor underneath the sphere is tinted red,

\- the inside of the left-corridor is visible even though the direct lightning (as guarded by the shadow) doesn't get there.

For comparison, here's the same scene with direct lightning only - you can intuitively feel it is somewhat less realistic, more rough, less deep:

https://preview.redd.it/em24cszs19va1.png?width=1056&format=png&auto=webp&v=enabled&s=30fb5235a356284252df683f3726db19618c6d47

... and the same scene using Bevy's default renderer:

https://preview.redd.it/1r6yf28v19va1.png?width=1056&format=png&auto=webp&v=enabled&s=e7d5b4dc6d152b043baadd7c375443d1557e5245

Note that on the screenshot above you can also see the inside of the left-corridor, but that's just because Bevy uses ambient lightning to light everything visible in the camera - the difference is best seen with a larger corridor:

Strolle's illumination model

Bevy's illumination model

For fun, here's how everything looks like without textures:

https://preview.redd.it/yj3r2wx329va1.png?width=1056&format=png&auto=webp&v=enabled&s=9426154a7871bd33819ff3fc27f98bd3a2d30a81

https://preview.redd.it/gcqbbbd529va1.png?width=1056&format=png&auto=webp&v=enabled&s=bf49f3e43cad3c0c78984d138b04880b1484df42

And, as is the custom, here's The Cornell Box!

https://preview.redd.it/j7dqr42629va1.png?width=1056&format=png&auto=webp&v=enabled&s=ef758585425508109147ab42d2cacaa10d926c65

As for the algorithmic side - Strolle approximates global illumination by ad-hoc voxelizing the scene into a 6D hashmap of position and normal (you might want to zoom-in to see the voxels):

\(voxel map, kinda extra-smoothed-out by image compression here\)

... estimating GI for each visible voxel, and then sampling a few (1-3) nearby voxels for each visible pixel, which performs kind-of-denoising at once (since one could consider voxels to be like a world-space spatial & temporal denoising mechanism).

Note that on all of the screenshots above, there's no denoising applied per-se - that's just how it looks like when you sample the voxel map directly.

For simplicity (and performance), the algorithm doesn't perform any collision-resolving - we just utilize Z-order curve to prevent nearby cells from colliding with each others, which turned out to work pretty well in practice (at least on the current test scenes).

Technical-wise, we're using software ray-tracing backed-by a couple of rust-gpu shaders (and raster pass for detecting primary hits) - the goal here is to create a relatively simple engine that doesn't require GPU with hardware ray-tracing capabilities, and can still generate a good-looking image.

All goes pretty well so far:

\- Cornell Box runs at 90 FPS (1024x1024) on my M1 Pro,

\- The Dungeon Sceneℒ️ gets around 40-60 FPS (1024x1024, M1 Pro), but I've still got a few optimizations left to apply, so I'm hoping to extract some more frames here.

More info & a couple of videos:

\- https://twitter.com/Piterolex/status/1649148596627861520

\- https://twitter.com/Piterolex/status/1642254962427154433

... and, of course, link to the code:

https://github.com/Patryk27/strolle

(voxel\~ish GI hasn't been merged yet, and there's lots of missing documentation, so it's not really usable yet, though πŸ˜‡)