Shooting Rays

Now it's time to get to the very core of ray tracing, e.g. shooting the rays;
But first we will create a header file which contains commonly used math constants and functions.
Create a file called Math.H

#ifndef _Math_H
#define _Math_H

#include <math.h>
#include <OSL/Imathx.h>

#define M_INFINITY 1.0e38
#define M_EPSILON  1.0e-10

#endif // Math.H

That's all there is to it for now, we will come back to this file in later tutorials.

Now for the interesting part!
We define the Ray class in a file called Ray.H according to this:

#ifndef _Ray_H
#define _Ray_H

#include <iostream>
#include "Math.H"

class Ray {
public:
    // Initialize ray with undefined origin and direction
    Ray()
        : mint(0.0f),
          maxt(M_INFINITY),
          time(0.0f),
          depth(0)
    {
    }

    // Initialize ray with origin and direction
    Ray(const Vec3 &orig,
        const Vec3 &dir,
        Float start,
        Float end = M_INFINITY,
        Float t = 0.0f,
        int d = 0)
        : o(orig),
          d(dir),
          mint(start),
          maxt(end),
          time(t),
          depth(d)
    {
    }

    // Initialize ray from origin, direction and parent ray
    Ray(const Vec3 &orig,
        const Vec3 &dir,
        const Ray &parent,
        Float start,
        Float end = M_INFINITY
        )
        : o(orig),
          d(dir),
          mint(start),
          maxt(end),
          time(parent.time),
          depth(parent.depth + 1)
    {
    }

    // Function operator for ray
    Vec3 operator()(Float t) const
    {
        return (o + d * t);
    }

    // Print ray to stream
    friend std::ostream& operator<<(std::ostream &stream, const Ray &r)
    {
        stream << r.o << "->" << r.d
               << "e[" << r.mint << ", " << r.maxt << "]"
               << ", time: " << r.time
               << ", depth: " << r.depth;
        return stream;
    }

    // Public data
    Vec3 o;
    Vec3 d;
    mutable Float mint, maxt;
    Float time;
    int depth;
    int depth;
};

#endif // Ray_H

A ray consists of a starting point and a vector, where o the the point of origin and d is the velocity vector.
Shooting rays is described as a parametric equaltion r(t) = o + dt, which is equal to a point in space at a certain value of the parameter t. We also keep the maximum and minumum values of t in the vector class, as this makes it possible to remember where the ray intersected a shape.

Some ideas for the ray interface has been "borrowed" from the the Physically Based Rendering Techniques Renderer, a.k.a pbrt, enjoy!

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License