Stencil method to reduce light leaks from adjacent spaces

Scenario: Creation of images showing the distribution of illuminance across a workplane from a high viewpoint and using the fore clipping plane to remove foreground objects.

Problem: With arbitrary shaped/orientated workplanes it is generally not possible to avoid including adjacent spaces and wall voids etc. in the final image. I usually create a stencil rendering for the same view parameters showing just the workplane (now set to "glow") and use those pixels to pick-out the pixels I want in the illuminance rendering (say, to profile the illuminance distribution across the workplane). See the top two images in this PDF:

Now, this method works fine most of the time provided that you can crank-up the ambient parameters to avoid light leaks. These can be fairly nasty when they do occur -- the pixels affected by a leak can have an illuminance much higher than nearby unaffected pixels. In the example shown, the leaky pixels have a value >1000x (!) that of their non-leaky neighbours. Needless to say, these affected pixels play havoc with any numerical measure of illuminance that you might want to get from your image. The computational cost of leak prevention can be expensive [1].

I've long had this hunch that the propensity for leaks might be reduced if we could prevent rpict from doing any initial sampling off the workplane, and so avoid populating the ambient file with outside and wall-void values at the zero level. It turns out that it can't be done directly with rpict. However there is a way using rtrace and potpourri of other Radiance programs. I couldn't figure out how to do it. Fortunately, Greg could -- he came up with this suggestion:



Rpict isn't very good about working on subimages, unless they're perfectly rectangular. However, you can use rtrace to accomplish this, with a little effort. Basically, you need to zero out the ray directions on all pixels you don't want computed. Something like:

  vwrays -ff -x 512 -y 512 -vf best.vf \
    > rlam -if6 - -if1 '\!pvalue -h -H -df -b stencil.pic' \
    > rcalc -if7 -of -e '$1=$1;$2=$2;$3=$3' -e 'out(v)=if($7-.5,v,0)' \
      -e '$4=out($4);$5=out($5);$6=out($6)' \
    > rtrace -ffc `vwrays -d -x 512 -y 512 -vf best.vf` -i scene.oct \
    > stencilled_ill.pic

If I didn't mess up, irradiances should be calculated wherever the stencil pixels are greater than 0.5, and zeros will be written to the output picture everywhere else. You can tweak the definition of the out(v) function to get a range of values, instead.


Which worked first time! Indeed, the approach does seem to be very effective. The lower two images in the PDF show the "usual rpict method" and the "stencil method" renderings set to the same falsecolor scale (in Photosphere). In addition to preventing the leak, the stencil method was four times faster (I expected it to be quicker, but not by this much). Both renderings were, of course, generated using the same ambient parameters -- in this case:

-ab 2 -ad 2048 -ar 128 -aa 0.2 -as 512

These need to be included in the rtrace command for the stencil method. The effectiveness in terms of leak prevention and increased speed will be highly dependent on the scene, the view and the ambient settings. As ever, some testing is advised.

For me at least, this is a very useful technique. And thanks to Greg for figuring out the command.

A (slightly belated) Happy (Chinese) New Year to you all.


[1] Much like watery leaks as anyone who has recently had dealings with a plumber will know. Sadly, my plumber will not accept payment in CPU cycles.

Dr. John Mardaljevic
Senior Research Fellow
Institute of Energy and Sustainable Development
De Montfort University
The Gateway
+44 (0) 116 257 7972
+44 (0) 116 257 7981 (fax)

[email protected]

Hi John and Greg.

Thanks for sharing this tip. I tried it on a simple scene and it works
nearly out of the box:

  vwrays -ff -x 512 -y 512 -vf best.vf \
    > rlam -if6 - -if1 '\!pvalue -h -H -df -b stencil.pic' \
    > rcalc -if7 -of -e '$1=$1;$2=$2;$3=$3' -e 'out(v)=if($7-.5,v,0)' \
      -e '$4=out($4);$5=out($5);$6=out($6)' \
    > rtrace -ffc `vwrays -d -x 512 -y 512 -vf best.vf` -i scene.oct \
    > stencilled_ill.pic

I had to change the 'rlam' command in the second line to

  > rlam -if6 - -if1 '!pvalue -h -H -df -b stencil.pic' \

i. e. no backslash in front of the exclamation mark.

After that I created a view of the scene and a falsecolor image from the
illuminance picture and used pcomb to combine them:

pcomb -e 'ro=if(ri(1),ri(2),ri(3));go=if(gi(1),gi(2),gi(3));bo=if(bi(1),bi(2),bi(3))' \
       stencilled_ill.pic fc.pic scene.pic > combined.pic

This command uses the stencilled_ill.pic as a mask for the combination of the scene image
and the illuminance plot: where there is a bright pixel in the stencilled_ill.pic the value
of fc.pic is used, else it's the scene.pic. The result is a view of the scene with the
falsecolor workplane 'floating' in it. I'm sure there is a more elegant
way to do this but I'm happy with mine.

The only problem here is that pcomb requires images of equal size. While resizing
the background to the exact resolution of the mask image is no problem, the falsecolor
image can have no legend. If you want to create a combined image with falsecolor legend
you have to add a space to the left of the scene.pic and the stencilled_ill.pic
before you combine the images.

If I can find some time I'll illustrate the whole process.


Hi Thomas,

The necessity of the '\' (backslash) character to escape the '!' depends on which shell you use. The C-shell requires it, whereas most other shells don't.

Regarding pcomb and the falsecolor legend, it's possible to cut the legend off using pcompos and reattach it also using pcompos after processing with pcomb, as an alternative method.