The RADIANCE Lighting Simulation and Rendering System

Gregory J. Ward /


1. Introduction

2. System Design Goals

2.1 Ensure Accurate Calculation of Luminance

2.2 Model Both Electric Light and Daylight

2.3 Support a Variety of Reflectance Models

2.4 Support Complicated Geometry

2.5 Take Unmodified Input from CAD Systems

3. Approach

3.1 Hybrid Deterministic/Stochastic Ray Tracing

3.2 Cached Indirect Irradiances for Diffuse Interreflection

3.3 Adaptive Sampling of Light Sources

3.4 Automatic Preprocessing of "Virtual" Light Sources

3.5 User-directed Preprocessing of "Secondary" Sources

3.6 Hierarchical Octrees for Spatial Subdivision

3.7 Patterns and Textures

3.8 Parallel Processing

One of the most practical ways to reduce calculation time is with parallel processing. Ray-tracing is a natural for parallel processing, since the calculation of each pixel is relatively independent. However, the caching of indirect irradiance values in Radiance means that we benefit from sharing information between pixels that may or may not be neighbors in one or more images. Sharing this information is critical to the efficiency of a parallel computation, and we want to do this in a system-independent way.

We have implemented a coarse-grained, multiple instruction, shared data (MISD) algorithm for Radiance rendering. This technique may be applied to a single image, where multiple processes on one or more machines work on small sections of the image simultaneously, or to a sequence of images, where each process works on a single frame in a long animation. In the latter case, we need only worry about the sharing of indirect irradiance values on multiple active invocations, since dividing the image is not an issue. The method we use is described below.

Indirect irradiance values are written to a shared file whose contents are checked by each process prior to update. If the file has grown, the new values (produced by other processes) are read in before the irradiances computed by this process are written out. File consistency is maintained through the NFS lock manager, thus values may be shared transparently across the network. Irradiance values are written out in blocks big enough to avoid contention problems, but not so big that there is a lot of unnecessary computation caused by insufficient value sharing. We found this method to be much simpler, and about as efficient, as a remote procedure call (RPC) approach.

Since much of the scene information is static throughout the rendering process, it is wasteful to have multiple copies on a multi-processing platform that is capable of sharing memory. As with value sharing, we wished to implement memory sharing in a system-independent fashion. We decided to use the memory sharing properties of the UNIX fork(2) call. All systems capable of sharing memory do so during fork on a copy-on-write basis. Thus, a child process need not be concerned that it is sharing its parent's memory, since it will automatically get its own memory the moment it stores something. We can use this feature to our advantage by reading in our entire scene and initializing all the associated data structures before forking a process to run in parallel. So long as we do not alter any of this information during rendering, we will share the associated memory. Duplicate memory may still be required for data that is generated during rendering, but in most cases this represents a minor fraction of our memory requirements.

3.9 Animation

3.10 Implementation Issues

4. Applications and Results

4.1 Electric Lighting

4.2 Daylighting

5. Conclusion

6. Acknowledgements

7. Software Availability

8. Bibliography

9. Appendix