diff options
Diffstat (limited to 'hw5/src/recursiveRaytracing.cpp')
-rw-r--r-- | hw5/src/recursiveRaytracing.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/hw5/src/recursiveRaytracing.cpp b/hw5/src/recursiveRaytracing.cpp new file mode 100644 index 0000000..eb19296 --- /dev/null +++ b/hw5/src/recursiveRaytracing.cpp @@ -0,0 +1,127 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527 */ +/* without consent of either the College of William & Mary or */ +/* Pieter Peers. */ +/******************************************************************/ +#include "ray_util.h" +#include "random_number.h" +#include "recursiveRaytracing.h" + + +////////////////// +// Constructors // +////////////////// +recursiveRaytracing::recursiveRaytracing(unsigned int maxDepth, unsigned int samplesPerPixel) +{ + _depth = maxDepth; + _samples = samplesPerPixel; +} + + +///////////// +// Methods // +///////////// +image recursiveRaytracing::render(const scene& s) const +{ + image result(s.getCamera().width(), s.getCamera().height()); + + // HW5: Implement a recursive ray tracer that shoots '_samples' rays per pixel. + // and has a maximum recursion depth of '_depth'. The ray tracer should + // only recurse for specular surfaces, and support environment maps and + // shadows. + // Modifes: nothing. + // Returns: rendered image. + + // for each pixel + for (image::size_type y = 0; y < result.height(); y++) { + + for (image::size_type x = 0; x < result.width(); x++) { + + // for sample size 1, shoot ray at pixel center + if (_samples == 1) { + ray r = s.getCamera()(x + 0.5, y + 0.5); + result(x, y) = traceRay(s, r, _depth); + } + else { + // for each sample, trace all the rays! + color pixel = color(0.0f); + + for (unsigned int i = 0; i < _samples; i++) { + ray r = s.getCamera()(x + random_float(1.0f), y + random_float(1.0f)); + pixel += traceRay(s, r, _depth); + } + + result(x, y) = pixel / _samples; + } + + } + + } + + return result; +} + + +color recursiveRaytracing::traceRay(const scene& s, const ray& r, unsigned int currentDepth) const { + color result = color(0.0f); + + // base case: bail at max depth + if (currentDepth == 0) { + return color(); + } + + // intersect the scene + intersectionPoint ip = s.intersect(r); + + // if hit, shade pixel + if (ip.isHit()) { + + // for each light source, + for (unsigned int l = 0; l < s.numberOfLightsources(); l++) { + // connect to light source + lightSample ls = s.getLightsource(l).intensityAt(ip.position()); + + // create shadow ray and intersect with light source + ray shadowRay = createRay(ip, ls.directionToLight()); + intersectionPoint shadow_ip = s.intersect(shadowRay); + + // if object not in shadow, shade it + if (!(ip.distance(shadow_ip) < ls.distance())) { + result += ip.shade(ls); + } + + } + + // if specular, compute indirect lighting and recurse + if (ip.getShaderProperties().specular) { + ray reflect_ray = reflectRay(ip); + intersectionPoint reflect_ip = s.intersect(reflect_ray); + + if (reflect_ip.isHit()) { + result += (ip.shade(reflect_ray.direction()) * traceRay(s, reflect_ray, --currentDepth)); + } + else { + // if scene has environment map, grab texel color from map + if (s.hasEnvironmentMap()) { + result += s.evaluateEnvironmentMap(reflect_ray.direction()); + } + + } + + } + + } + else { + + // if scene has environment map, grab texel color from map + if (s.hasEnvironmentMap()) { + result += s.evaluateEnvironmentMap(r.direction()); + } + + } + + return result; +} |