summaryrefslogtreecommitdiff
path: root/hw5/src/recursiveRaytracing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hw5/src/recursiveRaytracing.cpp')
-rw-r--r--hw5/src/recursiveRaytracing.cpp127
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;
+}