Extended Channel Film Plug-in for PBRT


Version 0.23



Written by Jared Sohn (sohn at alumni.cs.wisc.edu)


This page describes a film plug-in written for PBRT.  The default film plug-in only writes the red (R), green (G), blue (B), and alpha (A) channels. This plug-in can also write the depth (Z), world coordinates (wx, wy, wz), normalized surface normal vector (nx, ny, nz), coordinates from the parameterization of the surface (ou, ov), and primitive id (id) for each pixel and provides a framework for creating additional channels.


UPDATE 4/18/2012: You can now find the source on github.

UPDATE 7/15/2007: The below files use the v1.02 source. I have not tried this on v1.03 yet. If you are able to update this for v1.03, let me know, and I will update this page.


If you have any problems, notice errors, or make any patches, please let me know.


Installation Instructions


Follow these steps to install the plug-in on a Windows system. It shouldn't be too difficult to derive similar instructions for installing it on other operating systems.

1) This plug-in requires some minor changes to PBRT to allow channel data to be written by the film plug-in. Extract the following ZIP file into your v1.02 PBRT source directory or run a diff on the files and make the changes manually.


Updated PBRT files


2) Now extract the following ZIP file into your source directory to get the plug-in itself. Note that you will need to add the project file (win32/Projects/extendedchannelfilm.vcproj) to the PBRT solution file.


            extendedchannelfilm plug-in


3) Finally, compile PBRT and the plug-in and copy pbrt.exe into your PBRT bin folder and extendedchannelfilm.dll into your PBRT plug-in folder. (Typically both files should be copied to pbrt/bin/win32.)


Usage Instructions


1)      Within your .pbrt scene file, specify extendedchannelfilm as your film type.

2)      Indicate which channels you want by creating a string variable called channels which is set to a comma (or space) delimited list of channels. (i.e. "string channels" ["R G B A"] )

3)      If you would like to use a different set of channel names when you write an EXR file, create and set the following variable: "string renameas" ["red green blue alpha"]

4)      Here is a list of supported channels. 


R, G, B, A = red, green, blue, alpha

Z = camera depth (computed as distance from image plane.)

wx, wy, wz = world coordinates

nx, ny, nz = normalized surface normal vector components

ou, ov = coordinates from parameterization of the surface

id = unique id of last sampled primitive for a pixel.


Others can be created by modifying extendedchannelfilm.cpp [see below].  To my knowledge, none of these channels (besides R,G,B,A) have standardized names; if this is not the case, please let me know and I will update the source to conform to them.)

5)      You are allowed to repeat channel names, but not renameas names.  For example, you can render Z in greyscale by specifying channelname = 'Z Z Z' and renameas = 'R G B'.  If you duplicate a name in renameas, a warning will be displayed and it will be renamed as pbrt[index]_[origname].

6)      Every shape is automatically assigned a unique integer id from -1 to -INFINITY. If you would like to assign a particular id to a shape, you can create and set a float id variable within the .pbrt scene file. (It is typically better to assign a positive id since it avoids collisions with those assigned automatically.) Please note that the id will be written to the EXR file as a HALF channel rather than as a UINT channel because it allows a much larger range of values.

7)      I highly recommend downloading exrdisplay (as found here) to view your output files. Run exrdisplay -h for a list of options. I recommend running exrdisplay -c [channelname] -n [filename] to best view non-RGBA channels.


Here are a few example scene files:


Example 0

Example 1


Making Additional Channels Available


Channel data is sent to the image from the scene via rays. If the desired data is not available, you need to modify PBRT so that it is. To do so:


1) Modify geometry.h's Ray class such that it can store the desired data.

2) Modify scene.h's Intersect method to copy that data into the ray.

3) Modify the plug-in's ComputeVal() method such that it copies data from the ray into the film.  Also note that here you need to assign a name to the channel that will be referred to within .pbrt scene files.

4) Update GetMinBound(), GetMaxBound(), GetVarType(), ShouldAverage() as necessary.

5) Email me a patch and I'll make it available here for other PBRT users.


Potential Extensions


  • The plug-in determines a pixel's value for a channel by either taking the weighted average of the samples or by choosing the last sample. In the case of the shape id channel, it would be better to maintain a histogram over all samples for each pixel and choose the mode.
  • This plug-in contains most of the PBRT portion of the solution for exercise 8.10. That is, one can write additional tools to use these extended channels to 1) apply NPR effects detailed in Saito-Takahashi '90, 2) quickly rerender the scene with new light source positions, or 3) rerender with shifted viewpoints. I have personally implemented most of the first and am not certain if I will tackle the latter two.