An attempt at creating a raytracer in C++. Inspired from the C++ course at caltech found in the web. Docs below reproduce the data from their website
The vast majority of operations within a ray tracer rely on 3D vectors. The direction of a ray, the surface normal at a particular location on an object, the location of a light in the scene, all of these things and more are represented as vectors.
The ray tracer will also need a class to represent colors, since the whole point of ray tracing is to determine the color of each pixel in the image
Rays have two components, an origin P and a direction D. The direction is usually a normalized vector. The ray itself is modeled as another equation: P + D * t. The variable t only ranges over nonnegative values, since the ray starts from the origin point. When t = 0, the ray is at point P, and as t increases, the ray moves in the direction of D. (If D is normalized, notice that the ray has traversed a distance t at time t, which is sometimes useful to know...)
A class to represent each object in a raytraced scene. This class is an abstract base class, since there is no well-defined way that generic scene objects should behave. Eventually scene object will include detailed information about its surface characteristics, but for now objects will have one characteristic: their surface color.
Planes are specified by two values, a distance d from the origin, and a surface-normal N for the plane. Given these two values, the points in the plane satisfy this equation:
f(X) = X · N + d = 0
Thus, the plane class should have two data members:
A scalar specifying the distance of the plane from the origin. A vector specifying the surface normal for the plane.
Given the above values, the relevant equations for plane computations are:
For a ray P + D * t, the intersection point is: t = -(P · N + d) / (D · N) Only values of t >= 0 are considered intersections. Also, note that D · N can be 0, which also indicates no intersection. The surface normal of any point in the plane is simply N.
The sphere class should have two data members:
A vector specifying the sphere's center. A scalar specifying the sphere's radius.
Given the above values, the relevant equations for sphere computations are:
There can be 0, 1, or 2 intersections between a ray and a sphere. For a ray with the same formulation as before, the intersections are simply the solution to the quadratic equation: a * t² + b * t + c = 0 a = D · D b = 2 * (P · D - D · C) c = P · P + C · C - 2 * (P · C) - r² We use the discriminant to guide the computation, but with the additional constraint that we only want solutions where t >= 0. Also, notice that a will never be zero since the magnitude of D will never be zero. The surface normal of any point on the sphere is: n(X) = (X - C) / |X - C| In other words, subtract the point on the surface from the center, and normalize the resulting vector.
In order to actually see anything in a ray-traced scene, there must be some light source. We can also use lights to render shadows that objects cast on other objects. For now, we will have a very simple lighting model, where all lights are point-lights of a specific color.
Create a class to represent point lights, with the following state:
The position of the light The color of the light
A scene is simply a collection of scene-objects being raytraced, and another collection of lights illuminating the scene.