 | [TOC] Chapter 5: Managing Primitives & Intersections |  |
Managing primitives and intersections is crucial in rendering as it forms the foundation of how objects in a scene are represented and interact with light. Primitives, such as rays, spheres, or planes, are essential building blocks. Efficiently handling these primitives and calculating intersections - where rays of light meet these objects - is key to producing accurate and realistic images. Optimizing these processes ensures faster rendering by reducing unnecessary calculations, which is especially important in complex scenes with many objects.
 | Interacting with Primitives |  |
Primitives are the fundamental geometric shapes that make up the scene. These shapes can be spheres, triangles, planes, or any other geometric objects that rays can intersect. When rays are cast into the scene, the goal is to find which primitive(s) the ray intersects, if any, and at what points these intersections occur.
Ray-Primitive Intersection
The ray is usually represented by the parametric equation:
\[
\mathbf{R}(t) = \mathbf{O} + t \cdot \mathbf{D}
\]
Where:
- \(\mathbf{R}(t)\) is the ray at parameter \(t\),
- \(\mathbf{O}\) is the ray's origin,
- \(\mathbf{D}\) is the ray's direction,
- \(t\) is the distance along the ray.
Each primitive has its own intersection function, for example, for a sphere, the ray-sphere intersection can be found using:
\[
(\mathbf{R}(t) - \mathbf{C}) \cdot (\mathbf{R}(t) - \mathbf{C}) = r^2
\]
where:
\(\mathbf{C}\) is the center of the sphere,
\(r\) is the radius of the sphere.
Solving for \(t\) gives the intersection points.
Example: Ray-Sphere Intersection in JavaScript
class Sphere { constructor(center, radius) { this.center = center; this.radius = radius; }
intersect(ray) { const oc = subtract(ray.origin, this.center); const a = dot(ray.direction, ray.direction); const b = 2.0 * dot(oc, ray.direction); const c = dot(oc, oc) - this.radius * this.radius; const discriminant = b * b - 4 * a * c;
if (discriminant > 0) { const t1 = (-b - Math.sqrt(discriminant)) / (2.0 * a); const t2 = (-b + Math.sqrt(discriminant)) / (2.0 * a); return Math.min(t1, t2); // Return the nearest intersection point } return null; // No intersection } }
 | Aggregates |  |
In complex scenes, there are often a large number of primitives. Testing ray intersections with each individual primitive would be inefficient. An aggregate is a data structure that groups primitives together to accelerate intersection tests.
Aggregates aim to reduce the number of intersection tests required by organizing primitives into a spatial structure, such as bounding volume hierarchies (BVH) or kd-trees. Instead of testing all primitives, we first test against the bounding volumes or partitions, which helps to cull large portions of the scene where no intersection occurs.
Example: Simple Aggregate
|