Part 2: Soft Alpha Shadows
What we saw in the previous section worked well for hard shadows.
If we want soft shadows, things get a little trickier.
First take your scene

Here's the same scene that we started with before, except now there's an area light casting soft shadows.
camera { location <2, 4, -6> look_at <2, 1, 0>}
light_source {<-100,200,-100> colour rgb 1
area_light <20, 0, 0>, <0, 0, 20>, 10, 10
adaptive 1
jitter
}
#declare Stuff = union {
box {-1,1 translate y*3 pigment {rgb <1,1,0>}}
sphere {<3,3,0>,1 pigment {rgb <1,0,0>}}
}
object {Stuff}
plane {y, 0 pigment {rgb 1}}
The First Pass: Just the Shadows
Our first pass is to render just the shadows.
As before, we make the following changes:
- The scene is viewed from an orthographic camera placed vertically above the ground plane.
- The objects casting the shadows are no_image
The light strength is carefully adjusted so that it is just bright enough to be pure white.
In the previous version we were able to use a very bright light and rely on clipping,
but that produces poor results for the intermediate shades.
In this case the light needs to be rgb 1.9.
So the code now looks like this:-
camera { orthographic location y*10 look_at 0}
light_source {<-100,200,-100> colour rgb 1.9
area_light <20, 0, 0>, <0, 0, 20>, 10, 10
adaptive 1
jitter
}
#declare Stuff = union {
box {-1,1 translate y*3 pigment {rgb <1,1,0>}}
sphere {<3,3,0>,1 pigment {rgb <1,0,0>}}
}
object {Stuff no_image}
plane {y, 0 pigment {rgb 1}}
Turn the render into a 256-colour GIF
Use an image processing package to convert the result
of the first render into a 256-colour GIF file. By using a paletted image format
(like GIF) we can use the "transmit" keyword on the image_map.
We also need to use the image processing package to view the details of the palette and
discover which palette entry number corresponds to pure white.
In my particular case the palette entry is 230.
The Second Pass: putting it all together

We now render the whole thing. The significant features of this render are:-
- The objects are now no_shadow. We don't want real shadows to be cast this time.
- The camera and lighting go back to being what they were in the original scene.
- The plane is now painted (once) with an image_map mage from our 256-colour GIF
- The white part of the image map is mapped into invisibility.
- The grey and black parts of the image map are mapped into partial transparency.
So the code now looks like this:-
camera { location <2, 4, -6> look_at <2, 1, 0>}
light_source {<-100,200,-100> colour rgb 1}
#declare Stuff = union {
box {-1,1 translate y*3 pigment {rgb <1,1,0>}}
sphere {<3,3,0>,1 pigment {rgb <1,0,0>}}
}
object {Stuff no_shadow}
plane {y,0
pigment {image_map {gif "shadow2b.gif" once
transmit all 0.3 // dark bits partially transparent
transmit 230,1 // bright bits become 100% transparent
}
translate <-0.5, -0.5, 0>
scale <4/3*10, 10, 1>
rotate x*90
}
}
Back to Part 1: Hard Alpha Shadows
Back to Mike's Homepage
|