Graphics glossary 37 terms mentioned in this lesson
Select any term for a clear definition. The return button brings you back to the exact term link you used.
A completed picture is not the end of the renderer. It is the first point at which all of its responsibilities can be examined together. The camera generates samples, geometry supplies candidates, closest-hit traversal selects visibility, materials create local and secondary contributions, and the pixel averages the results. If any one of those stages is hidden behind the final scene, the course has produced an image without producing the understanding it was intended to develop.
We shall therefore finish by making an account. The laboratory separates primary, shadow, reflection and transmission rays, then counts primitive and bounding tests. It also compares linear sphere traversal with two simple bounded groups. The grouped version is not a full production bounding volume hierarchy. It is the smallest experiment that demonstrates why an acceleration structure can reduce work without changing the required closest hit.
What you should be able to account for
- Describe the complete route from pixel sample to final encoded colour.
- Use separate counters to explain where ray and intersection work originates.
- Apply an axis-aligned bound to reject a group and state what would be required to generalise the idea into a BVH.
The complete route
| Responsibility | Input | Output or decision |
|---|---|---|
| Pixel sampling | Integer pixel and sample offset | Normalised image coordinates |
| Camera | Sample coordinates and camera basis | Primary origin and direction |
| Primitive geometry | Ray and interval | Candidate hit record or miss |
| Scene traversal | Candidate records | Closest accepted record or any-hit answer |
| Material and light | Hit record, lights and path state | Local contribution and possible secondary rays |
| Path termination | Remaining depth and contribution policy | Continue or return a bounded result |
| Reconstruction | Linear sample contributions | Average linear pixel colour |
| Display encoding | Linear pixel colour | Stored RGB bytes for Canvas |
This table is a debugging route. A wrong pixel can be followed backwards to its sample positions, rays, hit records and material decisions. The stages are not independent in execution, but they have distinct criteria. Keeping those criteria visible prevents a plausible final colour from excusing an unexplained intermediate state.
Linear traversal has a clear cost
With R rays and N primitives, testing every primitive gives up to R × N primitive tests. Early any-hit exits and shrinking closest-hit intervals may reduce actual work, but the traversal still attempts many objects that are nowhere near the ray.
Adding samples multiplies primary routes. Shadows and recursive materials add secondary routes according to what those samples hit. The lesson counters therefore distinguish ray categories before reporting primitive tests. Render time alone is not enough: it varies with browser, device, background work and warm-up. The operation counts describe the algorithmic workload of this particular scene more directly.
Complete-renderer laboratory
Compare the Work of Two Traversals
Keep scene and sampling settings fixed, switch between linear and bounded sphere traversal, and compare the complete ray and intersection accounts.
Change this, then watch this: Change the traversal and render again. A correct result keeps the picture fixed while the primitive and bounding-test counts change.
- Primary rays
- Shadow rays
- Reflection rays
- Transmission rays
- Primitive tests
- Bounding tests
- Total traced rays
- Render time
Total rays and intersection work will be calculated after rendering.
What this establishes:
Reject a group using an axis-aligned box
An axis-aligned bounding box stores minimum and maximum coordinates on X, Y and Z. A ray can intersect the allowed parameter interval for each pair of slabs. If those three intervals do not overlap, the ray cannot reach anything wholly contained by the box.
function hitBounds(ray, box, tMin, tMax) {
for (let axis = 0; axis < 3; ++axis) {
const direction = ray.direction[axis];
if (Math.abs(direction) < 1e-12) {
const outside = ray.origin[axis] < box.minimum[axis]
|| ray.origin[axis] > box.maximum[axis];
if (outside) return false;
continue;
}
const inverse = 1 / direction;
let near = (box.minimum[axis] - ray.origin[axis]) * inverse;
let far = (box.maximum[axis] - ray.origin[axis]) * inverse;
if (inverse < 0) {
[near, far] = [far, near];
}
tMin = Math.max(tMin, near);
tMax = Math.min(tMax, far);
if (tMax < tMin) {
return false;
}
}
return true;
}
The laboratory puts spheres into two groups and computes a bound around each. A ray tests both bounds. Only a group whose box is hit has its member spheres tested. Planes remain outside because an infinite plane does not fit a finite world-space box. Triangles could be grouped in the same way, but the small demonstration keeps the before-and-after count easy to inspect.
When a bound earns its cost
A group contains ten spheres. Testing its box costs one bounding test. If the ray misses the box, ten primitive tests are avoided. If the ray hits the box, the bound has added one test and all ten spheres may still be examined. Acceleration is therefore not free. It depends on bounds that reject enough work and a hierarchy that narrows candidates efficiently.
From two groups to a hierarchy
A bounding volume hierarchy places bounds in a tree. The root encloses a large set. Child bounds divide it, and leaves reference small primitive groups. A traversal tests the root, descends only through intersected children and can order children by near distance to find a close hit earlier. A good build tries to balance the cost of more bound tests against the primitive tests they are likely to reject.
Our two groups demonstrate the rejection mechanism but not a general BVH builder, surface-area heuristic, dynamic update policy or robust traversal stack. Calling it a complete BVH would overstate the result. It is a bounded-group precursor whose counters let us see the operative idea before the data structure becomes elaborate.
Correctness remains the first gate
Switch between linear and bounded traversal. The rendered image should remain the same for the same sample positions and scene. Primitive-test counts should change; visibility should not. If the accelerated image differs, the lower count is not an optimisation result. It is evidence that a required candidate was incorrectly rejected or visited with the wrong interval.
This is the necessary order of judgement. First establish agreement with the simple traversal across deliberately difficult rays, including box boundaries, zero direction components and objects touching bounds. Then measure whether work or time improves. Speed obtained by skipping visible geometry is merely a faster wrong answer.
Decide whether the bound helped
A group contains 20 primitives. Across 1,000 rays, its box is missed 800 times and hit 200 times. Assume a hit tests all 20 members. Compare the primitive and bounding test counts with testing all group primitives for every ray.
Reveal the account
Linear traversal performs 1,000 × 20 = 20,000 primitive tests. The grouped traversal performs 1,000 bounding tests and 200 × 20 = 4,000 primitive tests. It replaces 16,000 primitive tests with 1,000 simpler bound tests in this account. Whether wall-clock time improves still needs measurement on the target implementation.
Read the manual renderer as source
The live course uses one cumulative source file so every lesson stage can be compared without loading a hidden service or external library. Open the browser ray tracer source and locate the vector operations, camera construction, three primitive tests, scene traversal, local shading, secondary-ray creation, sampling loop and metrics. The code is intentionally compact. Compactness is useful only while each responsibility can still be identified.
Canvas receives an ImageData buffer. It does not intersect a sphere, choose a triangle, cast a shadow or refract a ray. That boundary was stated in Lesson 1 and remains true in the completed scene. The browser API displays our answer; it has not answered the ray-tracing questions for us.
Perform the Part I audit
Select one ordinary diffuse pixel, one shadowed pixel, one mirror pixel and one glass pixel. For each, record the sample position, primary direction, first hit record and every secondary ray category it creates. Reconcile your four traces with the counters. Then switch traversal mode and confirm the final hits and colours remain unchanged while the test account changes.
Finally, add one small sphere outside both manual group bounds without rebuilding them. Observe the incorrect accelerated result, explain exactly which bound rejected the required primitive and repair the construction. This controlled failure is a better test of your understanding than another attractive arrangement of spheres.
The contract for the second half
The next fourteen lessons will implement graphics responsibilities through Vulkan rather than extend this JavaScript renderer. They should return to the artefacts we can now name: image coordinates, camera state, rays and intervals, triangle data, hit attributes, material parameters, secondary-ray state, sample accumulation and acceleration structure traversal. Vulkan will introduce explicit resources, shaders, command recording, synchronisation and hardware execution. Those mechanisms are not substitutes for the manual model. They are ways of organising and executing it at a different scale.
No Vulkan page is being filled with placeholder material here. Its sequence requires its own code baseline, device assumptions and validation plan. Part I ends with a working reference and an account against which that later implementation can be compared.
You have now constructed a ray traced scene by hand. The important result is not the arrangement of spheres. It is that a pixel can be challenged: which sample created it, which ray carried that sample, which interval admitted the hit, which surface record survived, which secondary routes contributed and what work was spent. When those questions have answers, the image is no longer a convincing black box.