Raytracer docs 🌐 EN

Accueil / Format de scène

Format de scène

Référence exhaustive du schéma JSON lu par SceneParser. Chaque clé documentée ici provient directement du parseur (srcs/core/scene/SceneParser.cpp) : rien n'est inventé. Les clés absentes de cette page sont ignorées silencieusement.

Structure d'un fichier

Une scène est un fichier .json (l'extension est vérifiée : tout autre suffixe lève INVALID_FILE_EXTENSION). Le document racine est un objet qui peut contenir quatre sections :

SectionTypeRequis ?Rôle
cameraobjetobligatoirePoint de vue et qualité du rendu. Son absence lève « Missing camera section ».
objectstableauobligatoirePrimitives, lumières et groupes. Son absence lève « Missing objects section ».
environmentobjetoptionnelCoefficients d'éclairage global.
materialstableauoptionnelBibliothèque de matériaux référencés par nom.

Le parseur ne lit que les clés qu'il connaît. Toute clé racine inconnue (par exemple un champ name ou description au niveau du document, ou n'importe quelle métadonnée) est simplement ignorée, sans avertissement.

{
  "environment": { "ambient": 0.4, "diffuse": 0.6 },
  "camera":   { "resolution": [1920, 1080], "position": [0,-100,20], "rotation": [0,0,0], "fieldOfView": 72.0 },
  "objects":  [ { "type": "sphere", "position": [60,5,40], "radius": 25 } ],
  "materials": [ { "name": "Rouge", "model": "phong", "base_color": [255,64,64] } ]
}

Section environment

Facultative. Contrôle les coefficients d'éclairage global. Les deux clés doivent être des nombres ; toute valeur non numérique est ignorée et la valeur par défaut est conservée.

CléTypeDéfautRôle
ambientnombre0.4Coefficient de lumière ambiante global.
diffusenombre0.6Coefficient de contribution diffuse global.

Section camera

Obligatoire. Analysée par parseCamera. Quatre clés sont obligatoires ; leur absence (ou une forme invalide) lève une exception qui interrompt le chargement de la scène.

CléTypeRequis ?Rôle / erreur si absent
resolution[largeur, hauteur] (2 nombres)obligatoireDimensions de l'image en pixels. Absent : « Missing camera resolution ». Mauvaise forme : « Camera resolution must be [width, height] ».
position[x, y, z]obligatoirePosition de la caméra dans le monde. Absent : « Missing camera position ».
rotation[x, y, z] en degrésobligatoireOrientation en angles d'Euler. Absent : « Missing camera rotation ».
fieldOfViewnombreobligatoireChamp de vision (degrés). Absent : « Missing camera fov ».
samplesPerPixelentier > 0optionnelÉchantillons par pixel (anti-aliasing). Défaut : 5. Une valeur ≤ 0 lève « camera samplesPerPixel must be greater than 0 ».
samples_per_pixelentier > 0aliasAlias snake_case de samplesPerPixel, utilisé uniquement si samplesPerPixel est absent.
"camera": {
  "resolution": [1920, 1080],
  "position":   [0.0, -100.0, 20.0],
  "rotation":   [0.0, 0.0, 0.0],
  "fieldOfView": 72.0,
  "samplesPerPixel": 128
}

Section objects

Obligatoire : un tableau (sinon « objects must be a list »). Chaque élément est un objet doté d'une clé type (chaîne, obligatoire) qui détermine la primitive, la lumière ou le groupe à construire. Forme générale d'un objet :

{
  "type": "sphere",           // obligatoire — sélectionne le type d'objet
  "name": "Ma sphère",        // facultatif — libellé affiché dans l'interface
  "position": [60, 5, 40],    // propriétés propres au type (voir tableau ci-dessous)
  "radius": 25,
  "material": "Rouge"         // facultatif — nom d'une entrée de "materials"
}

Le parseur applique une table de gestionnaires : pour chaque objet, il parcourt les clés reconnues et n'assigne que celles présentes. Une clé non listée pour ce type (ou totalement inconnue) est ignorée. Si une clé présente a une valeur malformée, l'objet est abandonné (message d'erreur sur stderr) mais le reste de la scène continue de se charger.

Contrairement à camera, un objet invalide n'interrompt pas le chargement : l'erreur est écrite sur la sortie d'erreur et l'objet est simplement omis. Seules les sections camera/objects manquantes stoppent le parseur.

Types d'objets et clés reconnues

Valeurs acceptées pour type et clés lues par le parseur pour chacune. Les clés position, rotation, scale, name et material sont acceptées de façon générique ; les colonnes ci-dessous listent les clés spécifiques que chaque type exploite réellement.

typeClés propres au typeNotes
sphereposition, radius, scaleSphère centrée sur position.
planeaxis ("x"/"y"/"z"), position, sizePlan aligné sur un axe. Voir l'avertissement ci-dessous.
cubeposition, rotation, scale, sizeCube d'arête size.
cylinderposition, rotation, radius, heightCylindre.
coneposition, rotation, radius, heightCône.
trianglevertex0, vertex1, vertex2Trois sommets [x,y,z].
torusposition, rotation, radius, heightTore ; height sert de rayon de tube.
tanglecubeposition, rotation, size, thresholdSurface implicite (isovaleur threshold).
fractalposition, size, power, iterationsFractale (type Mandelbulb).
meshfile (.obj) ou vertices / faces / normals, position, rotation, scale, vertex_overridesMaillage chargé depuis un fichier ou défini en ligne.
point_lightposition, color, intensityLumière ponctuelle.
directional_lightdirection, color, intensityLumière directionnelle.
groupname, position, rotation, scale, childrenConteneur hiérarchique ; children est un tableau d'objets imbriqués.

Le plan se définit par axis, jamais par normal/origin. La clé axis attend la chaîne "x", "y" ou "z" (toute autre valeur lève « Unknown axis »). Des clés comme normal ou origin sont ignorées : un plan défini ainsi retombera sur son axe par défaut. Utilisez position (et non origin) pour le décaler le long de l'axe.

Clés génériques additionnelles reconnues par la table de gestionnaires : direction, power, threshold, intensity, iterations, vertices, faces, normals, vertex_overrides. Chaque entrée de vertex_overrides est un objet { "index": n, "position": [x,y,z] } ; une entrée sans index ou sans position lève une erreur.

Il existe aussi un type obj (distinct de mesh) qui importe directement un .obj via la clé path (obligatoire) et accepte position, rotation, size. Il produit une liste de triangles au lieu d'une primitive maillée unique.

Conventions de valeurs

NotionFormeDétail
Vecteur[x, y, z]Tableau de 3 nombres. Utilisé pour position, scale, direction, les sommets… Une mauvaise longueur lève « expected an array of 3 numbers [x, y, z] ».
Rotation[x, y, z]Angles d'Euler en degrés.
Couleur[r, g, b]Trois composantes entières comprises entre 0 et 255. L'alpha est fixé à 255. Mauvaise longueur : « expected an array of 3 numbers [r, g, b] ».
Résolution[largeur, hauteur]Deux nombres entiers.

Section materials et référence par nom

Facultative : un tableau de matériaux (sinon « materials must be a list »). Chaque entrée doit posséder un name (sans lui : « Missing material name ») et, en général, un model ("phong" ou "pbr"). Un objet réfère un matériau par sa clé material, qui doit correspondre exactement au name d'une entrée de materials.

Si la valeur de material d'un objet ne correspond à aucun matériau chargé, le parseur lève « Unknown material "…" » et l'objet concerné est abandonné.

Pour le détail exhaustif des champs de matériau (base_color, metallic, roughness, transmission, cartes de texture et de normales, etc.), voir la page Matériaux. À noter : le modèle est lu depuis model et non type ; une clé type sur un matériau est ignorée et le modèle retombe sur phong.

Exemple complet commenté

Extrait fidèle de tests/configs/subject.json (deux sphères, un plan et une lumière) :

{
  "environment": { "ambient": 0.4, "diffuse": 0.6 },

  "camera": {
    "resolution": [1920, 1080],      // largeur x hauteur en pixels (obligatoire)
    "position":   [0.0, -100.0, 20.0],
    "rotation":   [0.0, 0.0, 0.0],   // degrés (obligatoire)
    "fieldOfView": 72.0,             // degrés (obligatoire)
    "samplesPerPixel": 128           // anti-aliasing (défaut 5)
  },

  "objects": [
    {
      "name": "Sphere A",
      "type": "sphere",
      "position": [60.0, 5.0, 40.0],
      "radius": 25,
      "material": "Material A"        // référence par nom
    },
    {
      "name": "Plane",
      "type": "plane",
      "axis": "z",                    // "x" | "y" | "z" — PAS "normal"/"origin"
      "position": [0.0, 0.0, -20.0],
      "material": "Material C"
    },
    {
      "name": "Point light",
      "type": "point_light",
      "intensity": 1000000.0,
      "position": [400.0, 100.0, 500.0]
    }
  ],

  "materials": [
    // Le modèle est lu depuis "model" (phong | pbr) ; "base_color" en [r,g,b] 0-255.
    { "name": "Material A", "model": "phong", "base_color": [255, 64, 64] },
    { "name": "Material C", "model": "phong", "base_color": [64, 64, 255] }
  ]
}

Messages d'erreur du parseur

Les erreurs fatales interrompent le chargement (exception LoadingSceneException). Les erreurs par objet sont écrites sur stderr et l'objet fautif est simplement omis.

MessagePortéeCause
Missing camera sectionfatalPas de clé camera à la racine.
Missing objects sectionfatalPas de clé objects à la racine.
Missing camera resolutionfatalcamera.resolution absent.
Camera resolution must be [width, height]fatalresolution n'est pas un tableau de 2 nombres.
Missing camera positionfatalcamera.position absent.
Missing camera rotationfatalcamera.rotation absent.
Missing camera fovfatalcamera.fieldOfView absent.
camera samplesPerPixel must be greater than 0fatalsamplesPerPixel ≤ 0.
objects must be a listfatalobjects n'est pas un tableau.
materials must be a listfatalmaterials n'est pas un tableau.
Missing material namefatalUne entrée de materials n'a pas de name.
Missing object typepar objetObjet sans clé type (ou type non-chaîne) : objet ignoré.
object "<type>": Unknown or incomplete object definitionpar objetType inconnu ou propriétés insuffisantes pour construire l'objet.
object "<type>" <clé>: …par objetUne propriété est malformée (ex. : radius non numérique).
Unknown material "<nom>"par objetmaterial ne correspond à aucun matériau chargé.
Unknown axis "<valeur>"par objetaxis hors de "x"/"y"/"z".
Missing object pathpar objetType obj sans clé path.