Having a pause from handling files and editor is good, to at least update something in rendering and keep motivation high. So I went ahead and implemented voxel cone tracing global illumination (and reflections of course).
Anyways, image time:
Although quite dark, secondary shadows are visible. Note, global illumination is full integrated into the editor.
Reflective box, global illumination debug buffer (in Debug window), and color bleeding visible from spotlight.
Anyways so much for the show - so how is it done? In short:
- Scene is voxelized, during which phase lights and shadows are injected in.
- Reflection pass performs cone tracing, the cone angle is defined based on material properties
- GI pass performs cone tracing for global illumination
- Lighting pass has 1 fullscreen quad for indirect light (and reflections), and then 1 for each light (which I'd like to replace with tile-based method)
Resolution for reflection and GI pass can be any (therefore even sub-sampling can be done), actually in the images Scene is voxelized into 512x512x512 buffer, Reflection & GI pass are done at FullHD with 1x MSAA, and Lighting pass is done with 8x MSAA. Original G-Buffer generation is done at 8x MSAA. Everything is resolved later (actually even after the tone mapping pass).
I have an option to switch from voxel texture into sparse voxel octree, yet it is still heavily un-optimized (and slower), although having a lot smaller memory footprint. When I manage to find some more time for that, I'd like to switch over to sparse voxel octree only.
If possible, I'd like to re-visit resource management and dynamic re-loading, which would be a bit less 'showcase' and more 'coding' topic. Other than that, virtual shadow maps and virtual textures are going to be visit and attempted by me, hopefully in next weeks.
Side note: If you're trying to implement VXGI or voxelization on the GPU, and having some questions - I'll gladly answer them.
That should be it for today, thanks for reading!