Raytracer docs 🌐 FR

Home / Materials

Materials

A material describes how a surface looks: its colour, its shininess, its metal/roughness, its reflection and its transparency. The engine offers two illumination models — PHONG and PBR — and a common set of fields serialized identically in scene files and in the personal library. Everything on this page comes from srcs/common/Material.hpp and the SceneParser::parseMaterial function.

PHONG / PBR 25 fields Textures & normal maps Library ~/.raytracer/materials

Illumination models

Each material carries a model field that selects the shading model. Two values are recognized by the parser (case-insensitive); any other value raises a loading error.

modelModelWhen to use it
"phong"PHONG (default)Simple, fast materials: plastics, matte or painted surfaces, prototyping. Direct control through base_color, specular and shininess.
"pbr"PBRPhysically plausible rendering: metals, dielectrics, clearcoat, sheen. Control through metallic, roughness, ao and the advanced parameters.

The default model is PHONG (MaterialModel::PHONG). Fields for both models live in the same Material struct: a PBR material ignores shininess/specular when shading, and a PHONG material ignores the PBR parameters — but every field is still present and serialized.

{
    "name": "Matte red",
    "model": "phong",
    "base_color": [200, 40, 40]
}

PHONG model

The PHONG model combines three classic terms. The final colour of a lit point is the sum of an ambient component, a diffuse component (Lambert's law, proportional to N·L) and a specular component (glossy highlight).

TermFields involvedRole
Ambientbase_color, scene ambient coefficientUniform base lighting, independent of direct lights.
Diffusebase_colorMatte scattering: depends on the angle between the normal and the light.
Specularspecular, shininessGlossy highlight toward the viewer; shininess is the exponent that tightens the highlight (larger = smaller, sharper spot).

By default specular is [0,0,0] (no highlight) and shininess is 32. For glossy plastic, give a non-zero specular colour (for example a light grey) and raise shininess.

PBR model

The PBR model follows a metallic-roughness workflow: the base colour is the albedo of a dielectric and the reflection colour of a metal, while roughness controls the sharpness of reflections. Advanced parameters add clearcoat, sheen and transmission.

FieldRangeRole
base_colorRGB 0–255Albedo (dielectric) or metallic reflection colour.
metallic0–1Metalness: 0 = dielectric, 1 = pure metal.
roughness0–1Micro-surface roughness: 0 = sharp mirror, 1 = very diffuse.
ao0–1Ambient occlusion: attenuates ambient lighting.
specular_level0–1Strength of the dielectric specular highlight.
specular_tint0–1Tints the highlight toward the base colour instead of white.
clearcoat0–1Clearcoat: strength of a thin extra clear layer.
clearcoat_roughness0–1Roughness of the clearcoat layer.
sheen0–1Velvet-like effect at grazing angles (fabrics).
sheen_tint0–1Tints the sheen toward the base colour.
transmission0–1Fraction of light transmitted through the surface (translucent materials).

When shading in PBR, a metallic material (metallic close to 1) reduces its diffuse ambient component: the colour comes mostly from reflections. Remember to provide geometry and lights around a metal (see Tips).

Reflection and transparency

Four fields, shared by both models, drive secondary rays and opacity:

FieldRange / typeRole
reflectivity0–1Mirror reflection amount (reflected ray from the hit point).
transparency0–1Transparency: fraction of the ray transmitted through the surface.
iornumber (default 1.5)Index of refraction: bending of the transmitted ray at the interface (1.0 = air, ~1.33 = water, ~1.5 = glass).
alpha0–1Overall surface opacity (1 = opaque).

Without a skybox, highly reflective or transparent surfaces can appear dark where the secondary ray hits no lit geometry. See the Tips section.

All fields

The table below lists every field of the Material struct, with its JSON name, type, range, real default value and role. The "Alias" column shows the extra keys the parser accepts (camelCase variants).

JSON keyRecognized aliasTypeRangeDefaultRole
namestring"material"Material name (referenced by scene objects).
model"phong"/"pbr""phong"Illumination model.
base_colorRGB0–255[229,229,229]Base colour (albedo).
specularRGB0–255[0,0,0]Specular colour (PHONG).
shininessnumber> 032Phong specular exponent.
reflectivitynumber0–10Mirror reflection amount.
transparencynumber0–10Transparency.
iornumber≥ 11.5Index of refraction.
metallicnumber0–10Metalness (PBR).
roughnessnumber0–10.5Roughness (PBR).
aonumber0–11Ambient occlusion (PBR).
specular_levelspecularLevelnumber0–10.5Specular level (PBR).
specular_tintspecularTintnumber0–10Specular tint.
clearcoatnumber0–10Clearcoat strength.
clearcoat_roughnessclearcoatRoughnessnumber0–10.03Clearcoat roughness.
sheennumber0–10Sheen effect.
sheen_tintsheenTintnumber0–10.5Sheen tint.
transmissionnumber0–10Light transmission.
alphanumber0–11Opacity.
normal_mappath""Path to a normal map.
normal_map_enabledbooleanfalseEnables the normal effect (also accepts a non-zero number).
normal_scalenumber0–11Strength of the normal effect.
normal_noise_frequencynumber> 01Frequency of the procedural normal noise.
texture_mappath""Colour texture (PNG/JPG) sampled as base colour.
texture_map_enabledbooleanfalseEnables the colour texture (also accepts a non-zero number).
texture_uv_scalenumber> 01UV tiling factor.

Default colours are stored as floats in the struct (base_color = {0.9, 0.9, 0.9}) but are written as integer RGB on 0–255 in JSON, hence [229,229,229]. Unknown keys are simply ignored by the parser.

Textures and normal maps

A material can sample a colour texture and apply a normal perturbation. Images are loaded through stb_image (common formats: PNG, JPG, etc.), converted to RGB and cached by path (TextureCache), then sampled bilinearly with UV wrapping (repeat).

Colour texture

If texture_map_enabled is true and texture_map is non-empty, the point's base colour is read from the texture at the hit's uv coordinates, multiplied by texture_uv_scale (tiling factor). Raising texture_uv_scale repeats the pattern more often across the surface.

{
    "name": "Tiled floor",
    "model": "pbr",
    "roughness": 0.7,
    "texture_map": "tests/textures/tiles.png",
    "texture_map_enabled": true,
    "texture_uv_scale": 4.0
}

Normal maps

The normal_map field stores a path, and normal_map_enabled turns the effect on. The engine applies a procedural normal perturbation based on Perlin noise when the effect is enabled and no image path is given: normal_noise_frequency sets the scale of the relief and normal_scale (clamped to 0–1) how strongly it blends with the geometric normal.

The normal_map path and the normal_map_enabled state are kept and serialized identically, but the procedural relief in the render kernel kicks in when normal_map_enabled is true and normal_map is empty (Perlin noise). The colour texture, on the other hand, is genuinely sampled from the texture_map file.

Material library

Materials can be saved into a personal library (MaterialLibrary) located in ~/.raytracer/materials/. Each material is stored in a <name>.json file. The name is sanitized to form the filename: any non-alphanumeric character (other than - and _) becomes _, and an empty name becomes material.

OperationEffect
directory()Returns (creating if needed) ~/.raytracer/materials; empty if HOME is unset.
save(material)Writes <sanitized-name>.json (JSON indented with 4 spaces).
remove(name)Deletes the matching file.
loadAll()Loads every .json in the folder and sorts them by name; invalid files are skipped.

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. Colours (base_color, specular) are written as integer RGB [r,g,b] on 0–255.

Material market

The graphical interface provides a Material Market window (MarketWindow) with two tabs:

TabSourceHow it works
LocalLibrary ~/.raytracer/materialsLists saved materials (via loadAll()), with name search, a detailed preview and an Add button to inject them into the current scene.
OnlinePoly Haven catalogue (CC0)Fetches the texture list from api.polyhaven.com (via curl), showing thumbnails, author, categories and resolution. Add downloads the diffuse texture into ~/.raytracer/textures and creates a PBR material using it as texture_map.

Materials added from the Online tab are created as PBR (roughness ≈ 0.6, non-metallic), their base colour seeded from the thumbnail's average colour, then saved into the local library. The online tab needs a connection and the curl tool.

Examples

Three typical materials, in the format accepted by the scene parser and the library.

Matte plastic (PHONG)

{
    "name": "Red plastic",
    "model": "phong",
    "base_color": [200, 40, 40],
    "specular": [60, 60, 60],
    "shininess": 24.0,
    "reflectivity": 0.05
}

Brushed metal (PBR)

{
    "name": "Gold metal",
    "model": "pbr",
    "base_color": [212, 175, 55],
    "metallic": 1.0,
    "roughness": 0.25,
    "ao": 1.0,
    "specular_level": 0.5,
    "reflectivity": 0.4
}

Transparent glass (PBR)

{
    "name": "Glass",
    "model": "pbr",
    "base_color": [230, 240, 245],
    "roughness": 0.02,
    "transparency": 0.9,
    "transmission": 1.0,
    "ior": 1.5,
    "reflectivity": 0.1,
    "alpha": 0.2
}

Tips

The engine has no skybox: a secondary ray (reflection or refraction) that heads into the void returns no light. Metals and glass then appear dark. A few reflexes:

  • Surround reflective/transparent surfaces with lit geometry (a floor, walls, other objects) so reflections and refraction catch something.
  • Add lights visible from those surfaces (see Lights).
  • If a metal or glass stays too dark, lower reflectivity and transparency and raise the diffuse share (lighter base_color, lower metallic) to keep the surface readable.
  • For a sharp reflection, keep roughness low (PBR) or shininess high (PHONG); for a satin look, raise roughness gradually.