Skip to content

(Task 1) Generating Camera Rays

Nick Sharp edited this page Oct 20, 2017 · 15 revisions

"Camera rays" emanate from the camera and measure the amount of scene radiance that reaches a point on the camera's sensor plane. (Given a point on the virtual sensor plane, there is a corresponding camera ray that is traced into the scene.)

Take a look at Pathtracer::raytrace_pixel() in pathtracer.cpp. The job of this function is to compute the amount of energy arriving at this pixel of the image. Conveniently, we've given you a function Pathtracer::trace_ray(r) that provides a measurement of incoming scene radiance along the direction given by ray r.

When the number of samples per pixel is 1, you should sample incoming radiance at the center of each pixel by constructing a ray r that begins at this sensor location and travels through the camera's pinhole. Once you have computed this ray, then call Pathtracer::trace_ray(r) to get the energy deposited in the pixel.

Step 1: Given the width and height of the screen, and point in screen space, compute the corresponding coordinates of the point in normalized ([0-1]x[0x1]) screen space in Pathtracer::raytrace_pixel(). Pass these coordinates to the camera via Camera::generate_ray() in camera.cpp.

Step 2: Implement Camera::generate_ray(). This function should return a ray in world space that reaches the given sensor sample point. We recommend that you compute this ray in camera space (where the camera pinhole is at the origin, the camera is looking down the -Z axis, and +Y is at the top of the screen.) Note that the camera maintains camera-space-to-world space transform c2w that will be handy.

Step 3: Your implementation of Pathtracer::raytrace_pixel() must support supersampling (more than one sample per pixel). The member Pathtracer::ns_aa in the raytracer class gives the number of samples of scene radiance your ray tracer should take per pixel (a.k.a. the number of camera rays per pixel. Note that Pathtracer::gridSampler->get_sample() provides uniformly distributed random 2D points in the [0-1]^2 box (see the implementation in sampler.cpp).

Tips:

  • Since it'll be hard to know if you camera rays are correct until you implement primitive intersection, we recommend debugging your camera rays by checking what your implementation of Camera::generate_ray() does with rays at the center of the screen (0.5, 0.5) and at the corners of the image.
  • The code can log the results of raytracing for visualization and debugging. To do so, uncomment the #define ENABLE_RAY_LOGGING 1 near the top of pathtracer.cpp. After running the ray tracer, pressing S in the Scotty3D gui will show some of the traced rays.

Extra credit ideas:

  • Modify the implementation of the camera to simulate a camera with a finite aperture (rather than a pinhole camera). This will allow your ray tracer to simulate the effect of defocus blur.
  • Write your own Sampler2D implementation that generates samples with improved distribution. Some examples include:
  • Jittered Sampling
  • Multi-jittered sampling
  • N-Rooks (Latin Hypercube) sampling
  • Sobol sequence sampling
  • Halton sequence sampling
  • Hammersley sequence sampling
Clone this wiki locally