Simple Light-Sourced Clouds

 

A simple, fast method for faking illumination of a cloud texture using layered textures.
CONCEPT

 
Clouds are typically noisy patterns rendered with illuminated and shadowed areas. Because it is very simple to map light and dark colors to the high and low values of the noise function, this often goes only as far as rendering the edges (presumably thinner part) of the cloud light, and the center (presumably denser part) of the cloud dark .

This may be sufficient for some applications, however, directional lighting cues can often go a long way towards enhancing realisim.

One way to fake directional lighting is to shift the shadows away from the apparent light source. If the texture is broken down into two layers, it becomes a simple matter to assign the cloud shading to the bottom layer and the cloud outline to the masking top layer.


shading
 

mask
(checked areas are transparent)

composite with the mask
slightly shifted to the right

This is really just a primative bump mapping or embossing technique. The "shadowed" edges opposite the "illuminated" edges in the composite image enhance the effect, but are actually artifacts due to the semi-transparent mask which was used for the illustration. For implementation, the blue areas of the mask should be set to a transparency of 0.

 

IMPLEMENTATION

 
Implementing the core of the technique illustrated above is possible with a few lines of code:

#declare clouds = texture{
   texture{cloud_shading}
   texture{cloud_mask  translate lt_vec}  //where lt_vec is the light direction vector
 }

The not-so-easy part is of course in the details. Here is a break down of the points which needed addressing and how I approached them:

limit of effectiveness: There is a limit to the amount that the mask can be shifted after which inconsistancies will become visable and the effect will be lost. This limit is, roughly expressed, one half the diameter of the smallest feature. This may sound fairly restrictive. However, by judiciously blurring the edges of the mask and the transition from shadow to light on the shading layer, one can get away with a lot more.

edges:High contrast and well defined edges seem to work best - which seems to go almost counter to the very fluffy, fuzzy nature of clouds. This technique probably not suited for very fuzzy clouds or fogs. However, from our vantage point on the ground, many cloud forms do exhibit a moderately well defined boundary and given the aforementioned benefit of some edge blurring, an acceptable comprimise can be found. You will also notice that transition zone from shadow to light on the cloud shading layer should be fairly tight. This tends to produce denser looking clouds.

feature definition:This lighting effect stands out best when applied to relatively large, clumpy, cloud features, becomming less striking with grainy cloud textures.

apparent angle of lighting: Edge-on cloud illumination scenarios work best where either the angle of the sun or the apparent thickness of the cloud would limit the amount of broad diffuse lighting.

For illustration I've coded the relevent textures for POV as follows:

#declare sky_color= <0.11, 0.13, 0.59>; //blue sky
#declare c_bright = <0.99, 0.96, 0.88>; //illuminated color of clouds
#declare c_shade  = <0.62, 0.60, 0.70>; //shadow color of clouds

#declare cld_s  = .50; //cloud scale  
#declare cld_ts = .5; //cloud turbulence scale  
#declare cld_t  = .3; //cloud turbulence
#declare cld_c  = .40; //cloud cover
#declare cld_e  = .05; //fuzzieness of cloud edges
#declare lt_vec = x*.025; //illumination vector(light direction) 
                          //and "amount" of illumination 
#declare cld_is = .08; //softness of illumination
//-------------------------------

#declare cloud_shading=texture{
 pigment{
  bozo 
  scale cld_ts warp{turbulence cld_t lambda 2.8} scale 1/cld_ts 
  scale cld_s
  color_map{
   [0 color c_shade*.75]
   [cld_c-cld_is color c_shade]
   [cld_c color c_bright]
  }
 }
 finish{ambient 1 diffuse 0}
}

#declare cloud_mask=texture{
 pigment{
  bozo
  scale cld_ts warp{turbulence cld_t lambda 2.8} scale 1/cld_ts 
  scale cld_s
  color_map{
   [cld_c-cld_e*.5 color sky_color transmit 1]
   [cld_c+cld_e*.5 color sky_color transmit 0]
  }
 }
 finish{ambient 1 diffuse 0}
}

If you really need the whole scene file, simple_clouds.pov should give you something like the following:

There is still one serious limitation to this implementation, namely that if the sun is in the view frame, shifting the mask uniformly in one direction no longer works. Rather it would be necessary to radially shift the mask with respect to the location of the light source as projected onto the cloud plane. A black_hole type warp correctly positioned can shift the mask toward the "light source" point on a radial line. For example:

#declare sunpos=<-0.15, -.1, 0>; //projected sun position on the cloud plane
  warp {
    black_hole sunpos, 10000 
    strength .03                     
    falloff 0
  }

The following render was based on the above code.


 

CONCLUSION

 
While this technique of generating cheap clouds is not universally aplicable, I do believe it has some merit, even if only as the next step up from "traditional" noise clouds. However, the method of implementation presented should not be considered as the only (or best) approach. There are many improvments to be made.


Created by Abe Madey
bullfrog@taconic.net
Reproduction of content not permitted without express permission.
Updated 26.3.2002