1. Functions
A Primitive
's core functionality consists of computing
where a given ray intersects with it. Two functions exist that provide this functionality:
-
find_all_hits
-
find_first_positive_hit
find_all_hits
covers all ray-intersection related functionality:
it returns a list of all intersections. However, in practice,
we’re often only interested in the "first positive hit", that is, the
hit with the lowest positive t
-value, which
corresponds to the hit that’s closest to the eye and in front of it.

find_first_positive_hit
is specialized in finding this first positive hit
and therefore is a more efficient choice if one is only interested in this hit. For example, in the figure above,
find_all_hits
returns both \(H_1\) and \(H_2\), whereas find_first_positive_hit
would
only return \(H_1\).
As another example, consider the following situation:

Here, find_all_hits
will still return both \(H_1\) and \(H_2\), even though they occur behind the ray’s origin.
find_first_positive_hit
, however, will tell you that no hit has been found, as if it returns a hit,
it must take place in front of its origin.
2. Hit
A Hit
objects contains all relevant information about a single ray/primitive intersection.
We discuss each member variable in turn.
2.2. position
position
specifies where the hit took place in 3D Cartesian coordinates. It must
be consistent with the t
-value: if the hit was made by ray with origin \(O\) and
direction \(\vec\Delta\), position
must be equal to \(O + \vec\Delta \cdot {\tt t}\).
2.3. local_position
local_position
specifies the hit position with respect to the primitive’s own coordinate system.
-
local_position
has two components:xyz
anduv
. -
local_position.xyz
expresses the hit position in a 3D Cartesian coordinate system. -
local_position.uv
expresses the hit position in a 2D Cartesian coordinate system. -
local_position
is used by decorators. A 2D material will look at theuv
-component, whereas a 3D material will rely on thexyz
-component.
When implementing a shape primitive (e.g. a Sphere
, Cylinder
, Cone
, …)
the local_position
will coincide with the Hit
's position
member.
The position
and local_position
will diverge when the primitive is transformed:
transformers only update position
, but leave local_position
alone.
The reason for this is that an object’s color is not dependent on its position in the scene.
2.4. normal
The unit normal vector on the primitive at position
.

The orientation of the normal vector is important, as it is used by lighting algorithms to determine whether or not photons reach that point. For example,

The light ray reaching \(P_1\) is greeted with normal vector \(\vec n_1\) which points towards the light ray’s origin \(L\), whereas at \(P_2\) the light ray encounters \(\vec n_2\), which points away from the \(L\). The lighting algorithm interprets this as \(P_1\) receiving photons, while \(P_2\) does not.
Now consider the following setup:

Both eye and light source are inside the sphere. We expect the inside of the sphere to be illuminated by \(L\), but according to our lighting algorithm, it is not: the normal vectors will point away from \(L\) each time.
One way to solve this problem is to let Sphere
be smart about the direction of its normal vectors.
While computing hits, the primitive receives a ray whose origin represents the eye of the camera.
When determining the normal, it can choose its direction is such a way that it points towards this eye.
Mathematically, this can be done using the dot product: given the ray origin \(E\), the hit position \(P\) and a normal \(\vec n\) at \(P\), it computes \((E - P) \cdot \vec n\). If it is negative, the normal points towards \(E\), which is what we want. If, however, the dot product turns out to be positive, we need to flip the normal around: \(-\vec n\) becomes the new normal.
You can see this algorithm at work in SphereImplementation::compute_normal_at
.
2.5. material
material
contains the material which the scene object is made of at that point.
2.6. group_id
group_id
represents which group the intersected primitive is part of. This is important for edge detection.