Collect Shadows Using Message Passing Between Shaders

Most shadows rendered in PRMan are depth-based. Shaders usually samples shadow maps a lot of times for acceptalbe quality renders. It can be a very time-consuming task especially when "Soft Shadow" is concerned. Rendering shadows will inevitably slow down the fine-turning of texturing and lighting. Why must we spend so much time on that? How can we render a separate shdow pass?

Now we must rely on the message passing technique to let a surface shader know which part of the geometry appear to be __inShadow. __inShadow typically controls the use of ShadowColor in a light shader, but we can peek at it within a common illuminance loop in a surface shader, using the lightsource() function.

Note: In PRMan11, __inShadow is no longer a float, so use __inShadowC instead.

I write a simple template named zjCollectShadow and this is a simple test.

No light but the Key is visible. zjSpot is attached to the key light because it outputs the variable of __inShadowC.

 

 

 

 

 

SoftShadows are used.

 

 

 

 

 

 

 

 

The boxes are invisible in primary ray but they still cast shadows. Attach zjCollectShadow to the ground plane and call a constant white backplane, we get a render like this. It is the shadow pass to be saved.

 

 

 

 

Light the background without caring about the shadows.

 

 

 

 

 

 

 

 

Mutiply the shadow pass over the background, and feel free to apply any adjustment such as blur and level in 2D.

 

 

 

 

 

 

Then the boxes are back. Shadows are still necessary when they occlude each other in the shadow maps, but the render will be still much faster then render all the 3 passes together.

 

 

 

 

zj,March 2003