Cloud rendering and the relativity of whiteness

Here are some philosophical and rendering-related questions that I took home from the last vacation. What’s the color of clouds? The standard answer would be, white.
What’s the color of snow? Again, white. Ok, then look at the following picture, where the snow seems considerably whiter. This is the case in almost all photos that I took.

There is an image on Wikipedia from the same general area on which the brightness difference between clouds vs snow is even more pronounced. If you look at the directly lit parts of the snow and consider it white (#ffffff), then the directly lit parts of the clouds are at most 50% grey (#bbbbbb). Is that an evidence of air pollution? Unlikely! (At least not in Tyrol).

Snow can be considered isotropic and lambertian, if it is not totally compressed to a smooth surface. I found some BRDF measurements for snow in [1], and they indicate it’s pretty much lambertian. This means that, to a first approximation, snow reflects light equally well in all directions. This is evident in real life when trying to make out the contours of runs when direct sunlight is missing. It is nigh impossible to estimate the slope visually!

Things are different with clouds. Most of the time, the size of the water droplets is larger than the wavelength, so Mie scattering takes over. This makes them strong forward-scatterers, as illustrated in this humble drawing:

Now, if most of the energy is scattered forward, it has to be missing when seen from the side, right? As a consequence, the shadow behind a cloud should be lighter than the shadow behind the solid object, even though the cloud is fully opaque. And so it is, see again the Wikipedia photo and compare the brightness of the cloud shadow with the brightness of the mountain shadow.

Things are different of course, if your viewpoint is inside the forward scattering lobe. The next photo was taken just minutes before the first one, while still in the valley. This is, relative to the location of the first photo, down the hill to the left. Did I say strong forward scattering?

Lessions for Rendering

Clouds and fog volumes, even when realized with particles, need a forward scattering term. This can cheaply be approximated with (\mathbf{V} \cdot \mathbf{L})^n, where n is an exponent that is somehow dependent on the thickness or density. It is very similar to a normalized Blinn-Phong distribution. Below is some pseudo code that illustrates the general idea. Even when combined with dead simple, planar cloud textures, the results can be stunning (see screenshot).

half transmittance = exp2( - cloudtexture.a * somefactor );
half exponent = 32 * transmittance; // some magic number
half intensity = ( exponent + 1 ) / 2; // cheap normalization
half3 color =
    cloudtexture.rgb * ( pow( max( 0, dot( V, L ) ), exponent ) * intensity );
half alpha = saturate( 1 - transmittance );
half4 result = float4( color, alpha );

References

[1] Hudson et al., “Spectral Bidirectional Reflectance of Antarctic Snow: Measurements and Parameterization”, J Geophys Res (3) 2006
http://www.npolar.no/npcms/export/sites/np/en/people/stephen.hudson/Hudson06_BRDF.pdf

One thought on “Cloud rendering and the relativity of whiteness

  1. Very nice! I just tried this with a very simple turbulence noise function and even that looks very cloud like! I’m quite amazed at how much that piece of shader code adds to a image.

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload the CAPTCHA.