SciVis 2017 Project 3: "rendr"

Assigned Mon Jan 30; Due Thu Feb 14 at 11:59pm

In this project you will build a direct volume renderer. You will combine 3D convolution with elements of graphics (a simple camera model, the over operator, and Blinn-Phong shading) to complete a tool that can make high-quality renderings of volume (3D image) datasets.


Same as in previous projects. The new directory in your CNETID-scivis-2017 repository, with the source files for this project, is called p3rendr. The library is called rnd, the executable is called rendr, and the reference executable is rrendr. Because of the amount of work in this assignment, working with a partner is encouraged.

Unlike with previous projects, this same code base (the p3rendr directory) will be largely re-used for project 4, to be assigned around Feb 9. Project 4 will involve some new vector visualization code (a p4vectr directory that hasn't been distributed yet), and it will involve accelerating and optimizing this p3rendr code. That is, Project 4 will involve two different directories (breaking the strict mapping between project number and directory name). If you partner with someone now for Project 3, you will also be partnering with them for the portion of Project 4 involving the p3rendr code. That partnership (carrying from Project 3 over to Project 4) does not count against your maximum number of 3 times that you can partner with the same person. You will be able to partner with someone different for working on the p4vectr code (and that will count against the 3 times you can partner with the same person).

For Project 3, your renderer will be single-threaded. For Project 4, you will have to make it multi-threaded, and measure the speed-up from being multi-threaded. To make your life easier for Project 4, you should be thinking now about how to organize code so that it will be thread-safe, when the time comes to execute in a multi-threaded way.

What to do

As with other projects, the best description of what to do lies mainly in the given source files, and reference executable rrendr. Run "./rrendr" to review the commands available, and run "./rrendr about" to see what will need to be implemented. Reading through and understanding the header file rnd.h is essential. The rndMath.h macro collection is much like mprMath.h from the previous project, but expanded somewhat.

The handling of these lines

/* v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v  begin student code */
/* ^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^  end student code */
is the same as in the previous assignment.

You will be editing the header file (rnd.h) to augment the definition of three structs: rndCtx, rndConvo (for storing the output of convolution computation), and rndRay (for storing the state associated with one ray marching through space). Thus, even more than in the previous project, your work will involve making multiple coordinate changes to multiple files. In some source files you may also add new functions, but these should be static functions (only for use within that source file). As before, you may not create new source files, or edit the Makefile.

At the start of the functions that you have to implement, there is a comment block that defines what the inputs and outputs to the function should be; this provides the technical definition of what a correct implementation should be. The reference implementation rmapr should conform to this.

The inter-relationship of functions in ray.c is one of the more complicated things that you have to understand for this project; this map of how these functions call each other may be helpful.

New in p3rendr is a mechanism that may help for enabling and disabling diagnostic print statements. Note that rnd.h includes this line:

extern int rndVerbose; /* global flag for debugging messages */
The rndVerbose global variable is defined in misc.c, and set to 0. You shouldn't change that, but you can set the value of rndVerbose via environment variable, with each run of rendr. Note this line in rendr.c:
rndVerbose = getenvInt("RND_VERBOSE");
which uses a getenvInt utility function, based on getenv, defined earlier in rendr.c. So if you, on the command-line:
export RND_VERBOSE=5
Then when rendr runs it will immediately set global rndVerbose to 5. If you want, you can condition all your debugging message with something like:
if (rndVerbose) {
   fprintf(stderr, "%s: hello\n", me);
if (rndVerbose > 3) {
   fprintf(stderr, "%s: hello ok we're really going to print a lot now...\n", me);
Then you can set different thresholds for what kind of debugging messages get printed when (how exactly is up to you), but all the debugging messages will go away once you either (on the shell) "export RND_VERBOSE=0" or "unset RND_VERBOSE". You may also want to add additional variables to the rndConvo or rndCtx structs to control debugging messages in a more fine-grained way (e.g., only for certain pixels of the rendered image). If you ensure that all such debugging is conditioned on rndVerbose being non-zero, it will be easy to turn them all off.

For Project 3 there is no additional work for 33710 students to do relative to 23710 students.

What to do and rendr commands to try

The commands here use "./rrendr"; you should make sure that you get the exactly same results by running "./rendr". There is new data in the scivis-2017 repository, which below will be referred to below as "$SCIVIS", in the data/3d subdirectory. Read the 00-info.txt file there to see a description of the datasets useful for this project.


The grade will be based on correctness (75%), debugging process (15%), and style (10%). If your code does not compile cleanly, with the Makefile,, and, provided, you will get a ZERO for correctness. Correctness will be evaluated with examples such as those above, and maybe some additional ones to test corner cases. Code that does compile (if there are compile errors that halt the generation of rendr) cannot be graded.

To get full credit for debugging process, you will prepare a write-up, submitted as p3rendr.pdf in your repository, which documents how you proved to yourself that your code is correct, ignoring the reference implementation. Supposing you had no reference implementation (as in the real world), what kind of datasets would you create, and how would you render them (with which parameters), to see if your code was correct? Below are the four major areas of concern for code correctness, which include the kinds of things you should be worrying about when writing and testing your code. For each of the four things, describe in your write-up what experiment(s) you performed to test the correctness of your code. An experiment is a procedure that produces a targeted comparison between your mental model of how things work, which how things actually do work. To document an experiment, you need to describe what the input data is (what new dataset(s) did you create by adding new capability to rendr sdg?), how you set up the rendering (how is rendr go being run), what you expected to see in the output, and what you actually got in the output. Include the generated images in the write-up, so it can be read and understood without executing any commands. Each of these four things should get about one page of text and writing in the write-up.

  1. Camera and ray geometry: the look-at point appears in the middle of the rendered image, the given up vector is upwards in the rendered image, things are appearing with the correct aspect ratio, the near and far clipping planes work to clip out parts of the world, and the field-of-view is correctly controlling how much is visible, and perspective versus orthographic projection works correctly.
  2. Transfer functions: Given the color and opacity functions specified as a sequence of control points, the right colors and opacities are computed for the lookup-table, and the lookup-table is being correctly indexed during rendering. Also, the opacities computed by rndTxfLevoy correctly achieve a fuzzy isosurface effect, independent of the gradient magnitude.
  3. Probing and Blending: All the blendings work correctly for all the probes for which the blending is meaningful (rndBlendOver only works for rndProbeRgba and rndProbeRgbaLit). Is rndBlendOver correctly handling the opacity correction as a function of ray step size (HW4 #2)?
  4. Lighting with Blinn-Phong and depth-cueing: The Blinn-Phong reflection model is working correctly (the ambient, diffuse, and specular terms are each correct), specular highlights appear where they ought to (you can specify a function and a camera so that you can predict where specular highlights should appear), and depth cueing works.
The correctness of convolution is not part of the debugging process credit; you can use the zramp datasets as noted above to test your convolution.

For the style points, keep in mind: