Dev Blog #28 | Foundry Fridays: Light at the End of the Tunnel
Author: Rambus,
published 1 year ago,
[h1]Light at the End of the Tunnel[/h1]
Hey Founders, My name is Mark and I'm thrilled to continue our series of ‘Foundry Fridays’ developer diaries, where we - the team behind Foundry - get to pull back the curtain and give you a glimpse into our process and progress.
Each entry is a deep dive into a specific aspect of the game, ranging from art, design, user experience, and more. Today I’ll be speaking on my role as a shader specialist on the Foundry team, so you can expect today’s entry to be more on the technical side. If you enjoy these more technically focused posts, please let us know on our [url=http://discord.gg/eqvCtNH]Discord[/url] channel, and we'll to create more in the future.
In this week's edition, we're shedding some “light” on an intricate aspect of our game - the rendering of our volumetric lighting. Volumetric ambient lighting creates realistically dark caves and crevices in Foundry, but we've hit a bit of a snag. An annoying blue fog shows up when our tunnels get too large. In order to explain how we tackled the blue fog issue, we need to give you a little backstory on how our game's lighting works.
Get ready to step out of the fog and into the light!
[img]https://clan.cloudflare.steamstatic.com/images//38913947/892d9cc493cc68c6e03b8c757f5ede07b34e487a.jpg[/img]
[h1]Where Does Light Come From?[/h1]
A game like Foundry is rendered with something called “deferred” lighting. In a deferred rendering project all geometry is written to a series of graphics buffers (GBuffers) that contain information like, albedo (color), specular, glossyness and normal. After all objects are drawn we run a single pass over the buffers to calculate the direct lighting information for each pixel. This creates nice highlights and directional lighting information that we are used to in modern games. But it doesn’t accurately simulate how lighting works; for that we need something called “bounce” (or ambient) lighting.
[img]https://clan.cloudflare.steamstatic.com/images//38913947/9c4e5fcc41e5fafe0d8829d9a04896e9e2ed382d.png[/img]
[h1]Volumetric Bounce Lighting[/h1]
When a light ray hits a surface it reflects and scatters around the area. This bounce is what fills a real room with light when you turn on a simple lamp. The deferred step I mentioned before does not handle any of these “bounces” and results in areas not directly lit by lights being pitch black. If you wanted to render all these bounces you would be doing something called ray tracing- a feature that is prohibitively costly performance-wise.
Normally games fill in a best guess for the bounce lighting with an ambient term, or even by baking the bounces into something called a lightmap texture. But Foundry is a fully dynamic world so this just won’t work. We instead create our own approximation of a volumetric ambient lightmap that updates in real time as the world changes. This structure is computed on the CPU and then the volumetric texture is shared with the GPU. We can simply use this value per-voxel to mask an ambient term to ensure caves are properly darkened while keeping our outdoor scenes nice and bright.
[h1]Fixing the Blue[/h1]
If you went deep into our itch.io demo you would know that large caves had a sky colored fog in the distance. This is because, although the lighting system knew about our volumetric ambient data- the fog did not!
[img]https://clan.cloudflare.steamstatic.com/images//38913947/c8d6ee88c2b93910a156b981f4d793e5139334df.png[/img]
To solve this, when we compute the fog value at a given location we mask it by the volumetric lighting. This helps keep the darkness “dark”. But when you make a truly MASSIVE cave it still breaks because cameras have something called a “clip distance”, a distance away from the camera where no more content can be rendered. At this distance we no longer have any cave walls to sample the ambient lightmap at- just a big void. The solution here was to take the ray projected by the camera to that pixel and “clamp” its length by the max draw distance and sample the lightmap at that location. Then if this value is fully bright, we draw the regular sky/clouds/fog, and if it’s fully dark we render black… and voila! We have massive (dark) caves:
[img]https://clan.cloudflare.steamstatic.com/images//38913947/bfd9d69ede02df8d86a4f6163c0066e2e1b60e6e.png[/img]
Obviously this system is more complicated and has many more parts than what we spoke about here- but this was a particular improvement that was always on my list to fix, and I think it improves the experience for those players hoping to spend their time in an underground voxel factory.
Until next time Founders.
-Mark