Home / Features
Features
Geometry, acceleration structures, lighting, materials and interactive tools available in the engine. Everything on this page reflects the project's actual code (scene parser, builders, material headers).
Primitives
Ten primitive types are recognized by the parser (SceneParser) and constructed by the
PrimitiveBuilder. Each primitive implements the IPrimitive interface
(intersection test, bounding box, material, properties). The type column is the value
of the "type" key in the JSON scene file.
| Primitive | type | Scene parameters | Description |
|---|---|---|---|
| Sphere | sphere | position, scale, radius | Analytic sphere, the base primitive. |
| Plane | plane | axis (x/y/z), position, size | Infinite plane oriented along an axis. |
| Cube | cube | position, rotation, scale, size | Analytic box (convertible to an exact 8-vertex mesh). |
| Cylinder | cylinder | position, rotation, scale, radius, height | Parametric cylinder. |
| Cone | cone | position, rotation, scale, radius, height | Parametric cone. |
| Triangle | triangle | vertex0, vertex1, vertex2 | Triangle defined by its three vertices (editable). |
| Torus | torus | position, rotation, radius, height | Torus (ring); radius = major radius, height = tube radius. |
| Tanglecube | tanglecube | position, rotation, threshold, size | Implicit surface (isosurface) controlled by a threshold. |
| Fractal | fractal | position, size, power, iterations | Fractal object rendered via distance estimation (Mandelbulb-style). |
| Mesh | mesh | file or vertices/faces/normals, position, rotation, scale, vertex_overrides | Triangulated mesh (.obj) with a local BVH and smooth normals (editable). |
The source file Mobius_strip.* exists in the repository, but this
primitive is not wired into the parser, builder or Makefile: it is not currently
available in a scene.
Acceleration geometry (AABB / BVH)
Two helper structures back the rendering: AABB (axis-aligned bounding box) and BVH (bounding volume hierarchy). Every primitive exposes its bounding box, which lets it be placed in the BVH and lets rays that miss it be rejected quickly. The construction is detailed in the BVH acceleration section.
Lights
Two light types are supported by the parser and builders. Each light implements ILight
(intensity, color) and is evaluated as direct lighting by the active renderer's model.
| Light | type | Parameters | Description |
|---|---|---|---|
| Point | point_light | position, color, intensity | Emits in all directions from a point (isotropic emitter), with distance attenuation. |
| Directional | directional_light | direction, color, intensity | Parallel rays (sun-like), with no position and no attenuation. |
Shadows
For each light and each hit point H, the engine casts a shadow ray
from a slightly offset origin (H + ε·N, where N is the surface normal)
toward the light:
- For a point light, the ray is a segment limited to the light distance
(
t_max = d − ε). - For a directional light, the ray goes toward
−directionwitht_max = +∞.
If an occluder blocks the path before t_max, that light's direct contribution is
discarded for this point; otherwise the diffuse and specular terms are evaluated. The offset
ε along the normal prevents shadow acne (the surface self-intersecting).
Materials
Materials (srcs/common/Material.hpp) follow one of two shading models:
PHONG (default) or PBR. They carry a
name and are referenced by that name from scene objects. The table below lists
all fields of the Material struct with their actual default values.
| Field | Type | Default | Role |
|---|---|---|---|
model | "phong" / "pbr" | phong | Shading model. |
base_color | RGB color | [229,229,229] | Base color (albedo). |
specular | RGB color | [0,0,0] | Specular color. |
shininess | number | 32 | Shininess (Phong specular exponent). |
reflectivity | 0–1 | 0 | Mirror-reflection amount. |
transparency | 0–1 | 0 | Transparency. |
ior | number | 1.5 | Index of refraction. |
metallic | 0–1 | 0 | Metalness (PBR). |
roughness | 0–1 | 0.5 | Roughness (PBR). |
ao | 0–1 | 1 | Ambient occlusion. |
specular_level | 0–1 | 0.5 | Specular level (PBR). |
specular_tint | 0–1 | 0 | Specular tint (toward the base color). |
clearcoat | 0–1 | 0 | Clearcoat: strength of the clear layer. |
clearcoat_roughness | 0–1 | 0.03 | Clearcoat roughness. |
sheen | 0–1 | 0 | Sheen (velvet-like) effect. |
sheen_tint | 0–1 | 0.5 | Sheen tint. |
transmission | 0–1 | 0 | Light transmission through the surface. |
alpha | 0–1 | 1 | Opacity. |
normal_map | path | "" | Normal map (image). |
normal_map_enabled | boolean | false | Enables the normal map. |
normal_scale | number | 1 | Strength of the normal-map effect. |
normal_noise_frequency | number | 1 | Frequency for procedural normal noise. |
texture_map | path | "" | Color texture (PNG/JPG) sampled as base color. |
texture_map_enabled | boolean | false | Enables the color texture. |
texture_uv_scale | number | 1 | UV tiling factor (repeats per unit UV). |
Material library
Materials can be saved to a personal library (MaterialLibrary) located
in ~/.raytracer/materials/. Each material is stored as a <name>.json
file (the name is sanitized: non-alphanumeric characters become _).
loadAll() reads every .json in the folder and sorts them by name.
Serialization (MaterialLibrary::toJson/fromJson) is
shared with the scene loader/saver: a material round-trips identically whether it
lives in the library or is embedded in a scene file. Colors (base_color,
specular) are written as integer RGB [r,g,b] on 0–255.
Reflections and transparency
The material fields reflectivity, transparency and ior
control mirror reflection, transparency and refraction respectively. They rely on
secondary rays spawned from the hit point: a reflection ray and a refraction ray,
cast with an ε offset to avoid self-intersection. The ior (index of
refraction) determines how the transmitted ray bends at the interface.
With no skybox, highly reflective or transparent surfaces can appear dark where the secondary ray meets no lit geometry.
BVH acceleration
Before rendering, the scene builds a bounding volume hierarchy
(BVHNode, via scene.buildBvh()). Each node holds a bounding box (AABB); a
ray that misses a node's box skips its entire subtree, greatly reducing the number of intersection
tests on busy scenes. Meshes additionally have a local BVH built over their
triangles, rebuilt when a vertex is edited (see Vertex editing).
Meshes and .obj import
A mesh loads a Wavefront .obj file (via ObjParser), derives triangles
(MeshTriangle), computes smooth normals (average of incident faces)
and builds a local BVH. A mesh can also be defined inline in the scene via
vertices / faces / normals, allowing it to be serialized
without an external file.
When a mesh provides inline geometry (non-empty vertices), it takes
precedence over any file path: this is how baked primitives (converted
to meshes) are stored.
{
"name": "Suzanne",
"type": "mesh",
"file": "tests/obj/suzanne.obj",
"position": [0.0, 0.0, 0.0],
"rotation": [0.0, 0.0, 0.0],
"scale": [1.0, 1.0, 1.0],
"material": "Blue"
}
Vertex editing
Primitives that implement IEditablePrimitive (in addition to IPrimitive)
can have their vertices moved directly in the viewport. Editable primitives:
| Primitive | Editable vertices |
|---|---|
| Triangle | its 3 corners (saved verbatim in the scene JSON). |
| Mesh | the unique (welded) vertices of the .obj — moving a shared vertex updates every incident face. |
Analytic primitives (cube, sphere, plane, cylinder, cone, torus, tanglecube, fractal) are not vertex-editable: select one and use Convert to Mesh to turn it into a triangle mesh, then edit it. A cube is baked exactly to 8 vertices / 12 triangles; other shapes are sampled (an infinite plane cannot be converted).
Mesh edits are stored as vertex overrides (vertex_overrides, in
object space) re-applied after the .obj is loaded; the .obj file is never
modified. After each edit the BVH is flagged for rebuild and the viewport updates.
The detailed controls (handles, axis lock, Vertex field, vertex navigator, shortcuts) are described in Graphical interface → Vertex editing.
Cluster rendering
The engine can distribute a render across several machines: a server splits the image into tiles and
hands them to connected clients, which send their pixels back. A server is started with
--server [PORT] and joined with --connect IP PORT. Communication uses
typed packets (join, scene push, render request, tile upload, render state). See
Architecture → Cluster.