Top: Contents
- 'Modern Hall, at dusk', based on a model by NewSee2l035
- Nearly all physically based rendering algorithms necessitate to perform ray tracing queries against some geometry. In Fermat this happens through a ray tracing context, which provides the following interface:
{
void create_geometry(
const uint32 tri_count,
const int* index_ptr,
const uint32 vertex_count,
const float* vertex_ptr,
const int* normal_index_ptr,
const float* normal_vertex_ptr,
const int* tex_index_ptr,
const float* tex_vertex_ptr,
const int* material_index_ptr);
void trace(
const uint32 count,
const Ray* rays,
Hit* hits);
void trace(
const uint32 count,
const MaskedRay* rays,
Hit* hits);
void trace_shadow(
const uint32 count,
const MaskedRay* rays,
Hit* hits);
void trace_shadow(
const uint32 count,
const MaskedRay* rays, uint32* binary_hits);
};
Notice how there are two types of rays that can be traced: Ray and MaskedRay. The first is specified by an origin, a direction, and a full [tmin, tmax] range specifying valid intersection distances.
The second is specified by an origin, a direction, a mask, and a single maximum intersection distance, tmax. The mask is used to allow masking out geometry at ray tracing time: the ray's mask is OR'ed against the triangles masks, and triangles which result in a non-zero mask get discarded.
The other difference is in the type of tracing queries that can be performed: regular trace() queries return the closest hit among all geometries, while trace_shadow() queries may return upon the first hit encountered during the traversal process, in practice simply answering the question: "is the given ray segment shadowed?".
Next: The Rendering Context