In the Valley of Gods Style Saturated Shadows in Blender Lightbake
In this post I will cover how to color the penumbra in light bakes in Blender 3D. This effect was inspired by the concept art for Valley of Gods’ concept art.
The now cancelled In the Valley of Gods title by the developers of Firewatch had some gorgeous concept arts. The work by Claire Hummel captured the imagination of many developers.
Recently we were working on a new DLC for our game Puzzling Places. The DLC is themed around ancient Egypt, and it felt like an appropriate time to pay some homage to the beautiful work done by Campo Santo studio. What I was specially interested in was the emotions and mood which the images have. Part of that is the strongly saturated red which covers the areas between shadow and light.
Our setup for how to do this in a light bake is quite straight forward, but before we get in to that, I want to cover why a colored penumbra looks so nice, and why you might decide to include it in your games. Jump to the implementation part if you are not interested in the theory of why this effect happens.
Colored Penumbra
Adding shadows to the transition between the shadow and light area is a stylistic choice which a lot of artists decide to add to their work. In the case of In the Valley of Gods however, it did feel right to have the added streak of saturated red. Why is that the case?
Usually when you see painters add color in the light-shadow transition, it is the result of a misunderstanding of how subsurface scattering works.
Have you ever seen a bottle of colored ink? Usually it has a very deep, almost black like color. But once you write with that ink, the color could be anything from black, blue to red. How does that work?
As light travels through a medium, different wavelengths of light get absorbed by the medium. Objects have different colors, because different materials absorb different wavelengths of light at different rate.
The longer light travels through a medium, the higher amount of specific wavelength the material absorbs.
When you write with ink, you apply a very thin surface of ink on paper. This means there is less of ink material for the light to travel through, compared to the bottle of ink. Because light spends less time in that medium, the final color you see differs.
This brings us to subsurface scattering. When light hits a surface, a portion of the rays penetrate deep in to the material. These rays bounce around the material for a while and eventually come out of the material somewhere around where they went in.
The light that comes out of the material after bouncing around it for a while usually has a more saturated color. The reason for that is that it spends a longer time in the medium, and the material has had more chances of absorbing whatever light which is not the color of the material.
In the case of skin, this means we would see a strong red color.
Here is where the misunderstanding comes in. Different materials allow different degree of light penetration. Adding subsurface scattering to metallic materials for example doesn’t make much sense.
There are two factors that affect how strong the subsurface scattering should be. One is how easily light goes into the material, second is how closely you are looking at the material.
Materials that are softer like skin, tend to allow more light penetration. This alone is a reason why artists might choose to take an artistic license to add tint to shadow transition. The association the effect has with soft, skin like materials, adds an overall sense of softness to a scene.
However, it usually looks straight out wrong, if the stylization isn’t taken far enough. Why is that not the case In the Valley of Gods? Here is my working theory.
Mie and Rayleigh Scattering
Mie and Rayleigh scattering is the reason why our sky has the colors it has. Rayleigh scattering scatters blue light around in random directions. This is why our sky is blue. This is also why our sunsets are red. During sunset, the light has to travel a longer path to get to us. Just like the example with ink, the longer this path is, the more chances there are for Rayleigh scattering to scatter away the blue color, and turn the light more and more to red/ yellow.
Mie scattering happens when light collides with bigger particles in the air. Think of dust and water particles and god rays, or diffuse lighting in a sandstorm. Mie scattering spreads the light around along the direction of the light. It makes shadows softer and results in beams that bounce around shadow casting objects to directly hit the shaded areas.
Similar to subsurface scattering, mie scattering causes some light beams to take a longer path to the surface. That also means that that light gets pushed more and more towards yellow and red due to Rayleigh scattering. On top of that, substances that are large enough to cause mie scattering sometimes absorb some colors themselves. A volume of sandstorm for example have a reddish tint. If you have been a few kilometers away from a forest fire, you will immediately notice that everything will turn more yellow.
How does this color the penumbra of shadows? In the case of the mie scattering, the penumbra, or the transition between light and shadow is exactly where light rays hit which have traveled longer through the medium. Similar to skin subsurface scattering, these rays have a strong tint of red, which causes the penumbra to also get a saturated color.
You need a very specific condition however in order to get this effect.
You need a low sun, that on its own means a long path through the atmosphere. You also need a long stretch of volume which is full of particles large enough for a significant amount of mie scattering to happen. This means something like high density of sand close to the ground (a desert) or a forest fire causing a large amount of smoke.
This is the reason why the In the Valley of Gods concept art creates such a strong vibe for me and sells a location in the middle of a desert. It physically makes sense.
I have personally seen tinted penumbra in areas around large forest fire. Although I didn’t mange to find matching references for a sandstorm in a desert. Please send me some if you know of any!
Enough of theory, time for implementation.
Implementation
Luckily we have some leads on how the lighting was done for the In the Valley of Gods trailer. Here is the tweet posted by Matthew Wilde, the technical artist by Valve.
The core idea is the following. You have two light sources. One is a very strong red, the other includes other colors as well. When the two are added together, you get a brighter but less saturated surface. If only the red light is used, then you would get a very saturated red.
The trick is to play around with the shadow settings of the red light, to make it softer and “bleed” into the shaded area. This is actually very similar conceptually to my mie scattering theory. The light rays that took a longer path in the dusty reddish air to hit the shadow transitions, could be thought as a second light source.
Clever as this trick is, it is quite inefficient. This can be fine for the needs of your project, if you dont have many objects. The problem with this method is that a second directional light requires you to rerender all objects from its point of view. That can massively increase the number of draw calls you need to do.
I have covered in other articles, how to do your own shadow mapping in Unity. If you do that, you can easily identify the shadow transitions and using PCF apply a soft tint in those areas. I won’t cover this further, since we will be switching to Blenders path tracer for this project.
For Puzzling Places, we bake all our lighting in a 8k texture. So what I wanted to have was a process to bake in the information I need in a texture, to be able to identify the light shadow transition.
The first step is to create a lighting setup similar to the concept art. A streak of light coming through a valley. I usually use a huge area lights, and giant cubes to create a light corridor with enough light bounces.
In order to be able to bake only the light information coming from the sunset, you need to ensure that the ambient lighting is set to zero. This means the sky box should be set to pure black.
What I want to get at the end is a map whose grayscale value represents whether the surface is directly hit by the sunset, or whether it is being illuminated due to light rays that have been scattered around the atmosphere due to mie scattering.
The first problem we have with the scene as we have it, is that there are too many bounces. The light which hits the surface can bounces back and hit the cubes, then bounce back and hit the surface again. This is not good, because if a surface is gray, we dont know whether it is due to the lights bouncing of the big cubes, or due to lights scattered by the mie scattering.
So the first task is to turn off light bounces from the cube.
In Blender, you can mark an object to be a shadow caster. This means the object only serves as a volume to indicate shadows and nothing else. You can also turn off in the Ray Visibility section the Diffuse rays. This means this object becomes invisible to light rays that have hit the surface of our scene, and are bouncing out towards the two cubes.
Turning these two off effectively eliminates the bounce light from the cubes onto our scene. Notice how the scene has gotten darker.
However, light can still bounce around our mesh itself. That is also not good for us. Because we want gray color to mean areas hit by the mie scattered light, and if light can bounce around the mesh itself, gray can also mean that that area is being exposed to global illumination from the surface itself.
To fix this, turn off the diffuse ray visibility for the mesh itself as well.
Now we end up with a render where everything white is being directly hit by the sun set, and areas that are gray indicate the areas being illuminated due to mie scattering and thick atmosphere. This is not quite 100 percent right, because tilted surfaces might also get the same gray, but for my usecase it is good enough.
Next comes a simple math trick in shader to mark out the areas which are the transition between light to shadow.
Visualizing the masking above, you get something like this:
After this, things are quite simple. You have a mask and with it you can blend between two different color transformations. For example you can add a strong red to the white areas.
Thanks for reading. As usual you can follow me on the various socials found on my website: https://ircss.github.io/