Math 155B – Topics in Computer Graphics – Spring 2019
 

Project #4 – Implement Multiple Distributed Ray Tracing features.

Overview:  You will implement distributed ray tracing, with (a) Anti-aliasing, and (b) Soft shadows and (c) Depth of field and possibly (d) Motion blur. You will also gain familiarity with setting up a scene in the course’s ray trace software

Due date:

(A) Progress report due on Tuesday evening, May 14.  Upload a PDF file to gradescope. These will be discussed in class on Wednesday. (please do not include PID numbers).

(B) Completed project due Friday, May 17, 10:00pm. Upload a main program and a PDF file to gradescope, and get graded in-person.

All projects:  Grading is an individual session with Nick Sieger or Professor Buss.  Your PDF upload to gradescope should discuss briefly both technical and artistic aspects of the project. It should include a couple pictures showing your results.

Getting started.  Download the zip file RayTrace_Project4.zip, full URL is:

https://www.math.ucsd.edu/~sbuss/CourseWeb/Math155B_2019Spring/Project_4/RayTrace_155B_2019.zip

1.      This is a large Visual Studio “Solution” consisting of six Visual Studio “Projects”.  The different projects are:

a.      RayTraceKd. This is main project, and the one you will modify for the project. The “.sln” Visual Studio Solution file for the entire solution is in this folder.  Open this file to open work with the project in Visual Studio. 
You will modify the two files RayTraceKd.cpp and RayTraceSetup155B.cpp for your project.
RayTraceKd.cpp has the high-level code for the ray tracing algorithm.
RayTraceSetup155B.cpp has the scene description. You may use this mostly as is, but you will also need to modify to update the scene and to better illustrate your distributed ray tracing.
RayTraceSetup2.cpp has the scene description of the picture on the cover of the textbook. You can see examples of all the features of setting up geometries for the ray tracer.
RaytraceKdMain.cpp is the main program. You probably do not need to modify this unless you add extra keyboard or mouse controls, and want to change which scene is rendered (with the MODE variable).

b.     OpenglRender – intended to give a quick and crude rendering of the scene in OpenGL, but is still only partially ported from legacy OpenGL to modern OpenGL. Updates to these features may be rolled out over the rest of the course.

c.      RayTraceMgr – helper functions for setting a geometric scene, or reading .obj or .nff files. You do not need to work with these files for your project.

d.     Graphics – handles the main ray tracing calculations of intersecting rays with objects. You do not need to work with these files for your project.

e.      DataStructs – includes the KdTree data structure, plus various other useful data structures. (Now partially superseded by STL.) You do not need to work with these files for your project.

f.       VrMath – include GlLinearR3, GlLinearR4 and other math packages. You do not need to work with these files for your project.

2.      Build the C++ Solution/Project.  Put all six folders together into a new folder named, say, “Project 4”.  In the folder RayTraceKd, find the Visual Studio Solution (.sln) file. Open this file to start Visual Studio. 

a.      The Explorer Window of Visual Studio should show all six projects. You should make sure that “RayTraceKd” is shown in boldface as the main project. If not, right click, and select “Set as Startup Project”. (It should be OK, but it has been a problem in earlier years.)

b.     Build the project as usual!  Wait a couple minutes for everything to compile. 

c.      You may also build and run the project in “Release” mode, but you should definitely do all program development in “Debug” mode with small render windows.  (Release mode runs 10-20 times faster!)

3.      Running the program:

a.      Keyboard controls: Arrows control view direction. Home/End moves the scene further away or closer.  Arrow keys with Shift pressed move the scene up and down, and left and right.
Pressing “R” resets the view to its original position.

b.     At first, you will see only crude shapes --- not ray traced.
Press SPACE to start the ray tracing. Then wait a few seconds. Keep the window small most of the time, otherwise it might take minutes to do the ray tracing.

c.      Whenever you change the view or the window size, it reverts to showing just triangles and parallelograms in OpenGL mode.  Press SPACE again to ray trace.

d.     Try changing the MODE variable (in RaytraceKdMain.cpp) and rebuilding to see other versions of the scene.

e.      Possibly helpful for debugging: a mouse click prints the x,y coordinates to the console window.

4.      Examine source code in RayTraceKd.cpp. 

a.      The routine RayTraceView is the top-level ray tracing routine. This is routine you will modify to do anti-aliasing (by subpixel jittering) and depth-of-field (by eye position jittering). 

b.     Find the routines CalcAllDirectIllum and ShadowFeelerKd. These are the routines you will modify for implementing soft shadows.

5.      Examine source code in RayTraceKdMain.cpp.  This is the main program; handles all windowing interfaces, keystrokes, etc.  Note where the variable MODE is used to control which scene is shown. You will make very minor modifications to this program, perhaps none.

6.      Examine source code in RayTraceSetup155B.cpp (and also in RayTraceSetup2.cpp). These define the geometric objects and lights and materials of two different scenes. One a simplified one (MODE==0), and one as shown on the book cover. Two others show how to read from .NFF and .OBJ files.  You will make some additions to RayTraceSetup155B.cpp to customize the scene to make your scene look good.
If you do motion blur, you will need to add an object to the scene that can be moved around.

7.      Your tasks: There are two aspects:
   First aspect: Implement (a) Anti-aliasing, and (b) Soft shadows, and (c) Motion blur. As an “extra” task (worth 2 points), implement (d) Depth of field.
   Second aspect: Change the contents of the scene, to make it more attractive, and illustrate your distributed ray tracing features. 
For instance, reposition objects and lights to make the soft shadows more apparent. Add some new aspect such as either a Bezier patch, or another texture map. You do not need to do a lot for this aspect, but should do enough to show you have learned how to do it.  
Hints follow:

8.      Anti-aliasing.  In RayTraceView, cast multiple rays to each pixel. Use jittered, stoachstic super-sampling.  The routine MainView.CalcPixelDirection currently takes integers i, j as inputs, but these can be replaced by floats to access subpixel locations. (This makes the code modification rather simple.)
It is suggested to have a variable that controls the number of subpixel locations, so you can experiment easily with 2x2 or 3x3 or 4x4 or 5x5 subpixel samples.

9.      Soft shadows.  The suggestion is to add a new parameter to the function ShadowFeelerKd, called displacement (for instance), which specifies a displacement added to the lights position. CalcAllDirectIllum can then call ShadowFeelerKd several times. You can arrange the displacements in a circular pattern or rectangular pattern. (Rectangular is probably easier.) If you lights are horizontal rectangles (like ceiling lights), this makes it easier too.

10.   Depth-of-Field.  

a.      To displace the eye position up and down in RayTraceView, use the methods GetPixeldU() and GetPixeldV (belonging to the CameraView member object MainView). These give vectors (VectorR3’s) giving the distance horizontally and vertically between adjacent pixels. Use suitably scaled random multiples of these values to jitter the eye position.

b.     You can no longer use CalcPixelDirection to get the ray direction.  Instead, call CalcPixelPosition, and subtract the eye position and normalize to get the ray trace direction.

c.      Use the random permutation method to jointly jitter the eye position and the subpixel location (and motion blur if you implement this.

11.   Motion blur.  Jitter the position of some object or objects, either just translation, just rotation, or translation and rotation combined. This may be the trickiest one to implement, since the KdTree by default uses a tight bounding box and this is not valid if the object is moving.  (Unless you a sphere with only rotation and no translation: and this is acceptable for the programming project!!!)

a.      To transform a general viewable object, use TransformWithRigid as defined in TransformViewable.h, using a RigidMapR3 as defined in LinearR3.h.           

b.     One way to make the object be handled correctly by KdTree: Modify the routines myExtentsFunc  and myExtentsInBox in RayTraceKd.cpp to check for the object number (objNum) of the moving object, and return a large box containing all possible positions of the moving object instead of calling CalcAABB or CalcExtentsInBox for that object. Another alternative is to test for an intersection of the ray with the moving object in all cases. In this latter case, the moving object does not need to be in the kd tree.

12.   For adding new objects or features to the scene. See the code in RayTraceSetup2.cpp for examples of how to build things like ViewableBezierSet’s (sets of  Bezier patches).

Hand in: Upload to gradescope

(A) By Tuesday evening: A PDF with one or two images showing your progress so far. These will be discussed in class on Wednesday.

By Friday evening:
(B.i) A PDF file showing two or more images of your scene, and give a description of the scene and its features. 
The description of the features should include descriptions of both technical aspects and artistic aspects of the scene. Include screen images of “before” and “after” pictures showing your scene with and without distributed ray tracing techniques.
Length: 2-3 pages, including pictures.
(B.ii) Your main program RayTraceKd.cpp.

Grading will be based on technical merit, creativity, and artistic merit.
  2+ points for Tuesday evening progress report.
  18 points for final Friday hand in
  2 points for motion blur

The two “aspects” are graded jointly in that extra good quality work on one aspect can compensate for less work on the second part.