gKit2 light
Classes | Typedefs | Functions
tuto_bvh2_gltf_brdf.cpp File Reference

bvh 2 niveaux et instances, charge un fichier gltf... + utilitaires... More...

#include <random>
#include <algorithm>
#include <vector>
#include <cfloat>
#include "vec.h"
#include "mat.h"
#include "color.h"
#include "image.h"
#include "image_io.h"
#include "orbiter.h"
#include "gltf.h"

Go to the source code of this file.

Classes

struct  Ray
 rayon. More...
 
struct  Hit
 intersection avec un triangle. More...
 
struct  BBoxHit
 intersection avec une boite / un englobant. More...
 
struct  BBox
 boite englobante. More...
 
struct  Node
 construction de l'arbre / BVH. More...
 
struct  BVHT< T >
 bvh parametre par le type des primitives, cf triangle et instance... More...
 
struct  Triangle
 triangle pour le bvh, cf fonction bounds() et intersect(). More...
 
struct  Instance
 instance pour le bvh, cf fonctions bounds() et intersect(). More...
 
struct  Brdf
 regroupe tous les parametres de la matiere du point d'intersection. More...
 
struct  Sampler
 generation de nombres aleatoires entre 0 et 1. More...
 

Typedefs

typedef BVHT< TriangleBVH
 
typedef BVHT< TriangleBLAS
 
typedef BVHT< InstanceTLAS
 

Functions

Node make_node (const BBox &bounds, const int left, const int right)
 creation d'un noeud interne. More...
 
Node make_leaf (const BBox &bounds, const int begin, const int end)
 creation d'une feuille. More...
 
Point hit_position (const Hit &hit, const Ray &ray)
 renvoie la position du point d'intersection sur le rayon. More...
 
bool has_normals (const Hit &hit, const GLTFScene &scene)
 verifie la presence des normales par sommet. More...
 
Vector hit_normal (const Hit &hit, const GLTFScene &scene)
 renvoie la normale interpolee au point d'intersection dans le repere de la scene. More...
 
Vector triangle_normal (const Hit &hit, const GLTFScene &scene)
 normale geometrique du triangle, si necessaire... ie si has_normals(hit, scene) == false... More...
 
bool has_texcoords (const Hit &hit, const GLTFScene &scene)
 verifie la presence des coordonnees de texture... More...
 
vec2 hit_texcoords (const Hit &hit, const GLTFScene &scene)
 renvoie les coordonnees de texture du point d'intersection, suppose que has_texcoords(hit, scene) == true More...
 
Color sample_texture (const vec2 &t, const ImageData &texture)
 
const GLTFMaterialhit_material (const Hit &hit, const GLTFScene &scene)
 renvoie la matiere du point d'intersection. More...
 
Color hit_color (const Hit &hit, const GLTFScene &scene)
 renvoie la couleur de base de la matiere du point d'intersection. More...
 
Brdf hit_brdf (const Hit &hit, const GLTFScene &scene, const std::vector< ImageData > &textures)
 evalue les parametres pbr (couleur, metal, rugosite) de la matiere au point d'intersection, en fonction des textures aussi, si necessaire More...
 
int main (int argc, char **argv)
 

Detailed Description

bvh 2 niveaux et instances, charge un fichier gltf... + utilitaires...

Definition in file tuto_bvh2_gltf_brdf.cpp.


Class Documentation

◆ Brdf

struct Brdf

regroupe tous les parametres de la matiere du point d'intersection.

Definition at line 534 of file tuto_bvh2_gltf_brdf.cpp.

Class Members
Vector n normale interpolee du point d'intersection
Color diffuse color.
Color F0 fresnel.
Color emission emission pour les sources de lumieres ou pas (= noir).
float metallic metallic / dielectrique.
float alpha rugosite de la micro surface.
float transmission transmission, transparent ou pas (= 0)

Function Documentation

◆ make_node()

Node make_node ( const BBox bounds,
const int  left,
const int  right 
)

creation d'un noeud interne.

Definition at line 114 of file tuto_bvh2_gltf_brdf.cpp.

115 {
116  Node node { bounds, left, right };
117  assert(node.internal()); // verifie que c'est bien un noeud...
118  return node;
119 }
void bounds(const MeshData &data, Point &pmin, Point &pmax)
renvoie l'englobant.
Definition: mesh_data.cpp:290
construction de l'arbre / BVH.
Definition: tuto_bvh.cpp:133

◆ make_leaf()

Node make_leaf ( const BBox bounds,
const int  begin,
const int  end 
)

creation d'une feuille.

Definition at line 122 of file tuto_bvh2_gltf_brdf.cpp.

123 {
124  Node node { bounds, -begin, -end };
125  assert(node.leaf()); // verifie que c'est bien une feuille...
126  return node;
127 }
void begin(Widgets &w)
debut de la description des elements de l'interface graphique.
Definition: widgets.cpp:29
void end(Widgets &w)
termine la description des elements de l'interface graphique.
Definition: widgets.cpp:404

◆ hit_position()

Point hit_position ( const Hit hit,
const Ray ray 
)

renvoie la position du point d'intersection sur le rayon.

Definition at line 365 of file tuto_bvh2_gltf_brdf.cpp.

365 { assert(hit.triangle_id != -1); return ray.o + hit.t * ray.d; }

◆ has_normals()

bool has_normals ( const Hit hit,
const GLTFScene scene 
)

verifie la presence des normales par sommet.

Definition at line 368 of file tuto_bvh2_gltf_brdf.cpp.

369 {
370  assert(hit.mesh_id != -1);
371  assert(hit.primitive_id != -1);
372  const GLTFMesh& mesh= scene.meshes[hit.mesh_id];
373  const GLTFPrimitives& primitives= mesh.primitives[hit.primitive_id];
374  return primitives.normals.size() > 0;
375 }
GLenum primitives() const
renvoie le type de primitives.
Definition: mesh.h:336
description d'un maillage.
Definition: gltf.h:115
groupe de triangles d'un maillage. chaque groupe est associe a une matiere.
Definition: gltf.h:99
std::vector< GLTFMesh > meshes
ensemble de maillages.
Definition: gltf.h:150

◆ hit_normal()

Vector hit_normal ( const Hit hit,
const GLTFScene scene 
)

renvoie la normale interpolee au point d'intersection dans le repere de la scene.

Definition at line 378 of file tuto_bvh2_gltf_brdf.cpp.

379 {
380  assert(hit.instance_id != -1);
381  assert(hit.mesh_id != -1);
382  assert(hit.primitive_id != -1);
383  assert(hit.triangle_id != -1);
384  const GLTFMesh& mesh= scene.meshes[hit.mesh_id];
385  const GLTFPrimitives& primitives= mesh.primitives[hit.primitive_id];
386 
387  // indice des sommets
388  int a= primitives.indices[3*hit.triangle_id];
389  int b= primitives.indices[3*hit.triangle_id+1];
390  int c= primitives.indices[3*hit.triangle_id+2];
391 
392  // normales des sommets
393  assert(primitives.normals.size());
394  Vector na= primitives.normals[a];
395  Vector nb= primitives.normals[b];
396  Vector nc= primitives.normals[c];
397 
398  // interpole la normale au point d'intersection
399  // attention : il faut utiliser la meme convetion barycentrique que la fonction d'intersection rayon/triangle !!
400  Vector n= (1 - hit.u - hit.v) * na + hit.u * nb + hit.v * nc;
401 
402  // transforme la normale dans le repere de la scene
403  const GLTFNode& node= scene.nodes[hit.instance_id];
404  // les normales ne se transforment pas exactement comme les positions...
405  // les sommets sont transformes par node.model, comment transformer la normale pour quelle reste perpendiculaire au triangle ? cf Transform::normal()
406  Transform T= node.model.normal();
407 
408  n= normalize( T(n) );
409  return n;
410 }
position et orientation d'un maillage dans la scene.
Definition: gltf.h:129
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Definition: vec.cpp:123
std::vector< GLTFNode > nodes
noeuds / position et orientation des maillages dans la scene.
Definition: gltf.h:151
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition: mat.h:21
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition: mat.cpp:181
representation d'un vecteur 3d.
Definition: vec.h:59

◆ triangle_normal()

Vector triangle_normal ( const Hit hit,
const GLTFScene scene 
)

normale geometrique du triangle, si necessaire... ie si has_normals(hit, scene) == false...

Definition at line 413 of file tuto_bvh2_gltf_brdf.cpp.

414 {
415  assert(hit.instance_id != -1);
416  assert(hit.mesh_id != -1);
417  assert(hit.primitive_id != -1);
418  assert(hit.triangle_id != -1);
419  const GLTFMesh& mesh= scene.meshes[hit.mesh_id];
420  const GLTFPrimitives& primitives= mesh.primitives[hit.primitive_id];
421 
422  // indice des sommets
423  int a= primitives.indices[3*hit.triangle_id];
424  int b= primitives.indices[3*hit.triangle_id+1];
425  int c= primitives.indices[3*hit.triangle_id+2];
426 
427  // postion des sommets
428  assert(primitives.positions.size());
429  Point pa= primitives.positions[a];
430  Point pb= primitives.positions[b];
431  Point pc= primitives.positions[c];
432 
433  // normale geometrique
434  Vector n= cross( Vector(pa, pb), Vector(pa, pc) );
435 
436  // transforme la normale dans le repere de la scene
437  const GLTFNode& node= scene.nodes[hit.instance_id];
438  // les normales ne se transforment pas exactement comme les positions...
439  // les sommets sont transformes par node.model, comment transformer la normale pour quelle reste perpendiculaire au triangle ? cf Transform::normal()
440  Transform T= node.model.normal();
441 
442  n= normalize( T(n) );
443  return n;
444 }
Transform model
transformation model pour dessiner le maillage.
Definition: gltf.h:130
Vector cross(const Vector &u, const Vector &v)
renvoie le produit vectoriel de 2 vecteurs.
Definition: vec.cpp:129
representation d'un point 3d.
Definition: vec.h:21

◆ has_texcoords()

bool has_texcoords ( const Hit hit,
const GLTFScene scene 
)

verifie la presence des coordonnees de texture...

Definition at line 447 of file tuto_bvh2_gltf_brdf.cpp.

448 {
449  assert(hit.mesh_id != -1);
450  assert(hit.primitive_id != -1);
451  const GLTFMesh& mesh= scene.meshes[hit.mesh_id];
452  const GLTFPrimitives& primitives= mesh.primitives[hit.primitive_id];
453  return primitives.texcoords.size() > 0;
454 }

◆ hit_texcoords()

vec2 hit_texcoords ( const Hit hit,
const GLTFScene scene 
)

renvoie les coordonnees de texture du point d'intersection, suppose que has_texcoords(hit, scene) == true

Definition at line 457 of file tuto_bvh2_gltf_brdf.cpp.

458 {
459  assert(hit.instance_id != -1);
460  assert(hit.mesh_id != -1);
461  assert(hit.primitive_id != -1);
462  assert(hit.triangle_id != -1);
463  const GLTFMesh& mesh= scene.meshes[hit.mesh_id];
464  const GLTFPrimitives& primitives= mesh.primitives[hit.primitive_id];
465 
466  // indice des sommets
467  int a= primitives.indices[3*hit.triangle_id];
468  int b= primitives.indices[3*hit.triangle_id+1];
469  int c= primitives.indices[3*hit.triangle_id+2];
470 
471  // texcoords des sommets
472  assert(primitives.texcoords.size());
473  vec2 ta= primitives.texcoords[a];
474  vec2 tb= primitives.texcoords[b];
475  vec2 tc= primitives.texcoords[c];
476 
477  // interpole au point d'intersection
478  // attention : il faut utiliser la meme convention barycentrique que la fonction d'intersection rayon/triangle !!
479  vec2 t= vec2( (1 - hit.u - hit.v) * ta.x + hit.u * tb.x + hit.v * tc.x, (1 - hit.u - hit.v) * ta.y + hit.u * tb.y + hit.v * tc.y );
480  return t;
481 }
vecteur generique, utilitaire.
Definition: vec.h:131

◆ sample_texture()

Color sample_texture ( const vec2 t,
const ImageData texture 
)

renvoie la couleur d'un pixel d'une texture/image chargee par read_gltf_images() todo : interpolation bilineaire des texels autour de t...

Definition at line 486 of file tuto_bvh2_gltf_brdf.cpp.

487 {
488  // retrouve les coordonnes de t dans l'image
489  int tx= int(t.x * texture.width) % texture.width;
490  int ty= int(t.y * texture.height) % texture.height;
491  // attention aux repetitions, les coordoornees ne sont pas toujours entre 0 et 1 !!
492  if(tx < 0) tx= -tx;
493  if(ty < 0) ty= -ty;
494 
495  // respecte la convention gltf, origine en haut de l'image...
496  ty= texture.height - 1 - ty;
497  // position du pixel dans l'image
498  size_t offset= texture.offset(tx, ty);
499 
500  // recupere la couleur du pixel
501  Color color= Color(texture.pixels[offset], texture.pixels[offset+1], texture.pixels[offset+2], 255) / 255;
502  if(texture.channels > 3)
503  // alpha / transparence, si disponible
504  color.a= float(texture.pixels[offset+3]) / float(255);
505 
506  return color;
507 }
representation d'une couleur (rgba) transparente ou opaque.
Definition: color.h:14

◆ hit_material()

const GLTFMaterial& hit_material ( const Hit hit,
const GLTFScene scene 
)

renvoie la matiere du point d'intersection.

Definition at line 513 of file tuto_bvh2_gltf_brdf.cpp.

514 {
515  assert(hit.mesh_id != -1);
516  assert(hit.primitive_id != -1);
517  const GLTFMesh& mesh= scene.meshes[hit.mesh_id];
518  const GLTFPrimitives& primitives= mesh.primitives[hit.primitive_id];
519  if(primitives.material_index == -1)
520  return default_material;
521 
522  assert(primitives.material_index < int(scene.materials.size()));
523  return scene.materials[primitives.material_index];
524 }
int material_index
indice de la matiere des primitives.
Definition: gltf.h:102
std::vector< GLTFMaterial > materials
matieres.
Definition: gltf.h:153

◆ hit_color()

Color hit_color ( const Hit hit,
const GLTFScene scene 
)

renvoie la couleur de base de la matiere du point d'intersection.

Definition at line 527 of file tuto_bvh2_gltf_brdf.cpp.

528 {
529  return hit_material(hit, scene).color;
530 }
Color color
base color.
Definition: gltf.h:60
const GLTFMaterial & hit_material(const Hit &hit, const GLTFScene &scene)
renvoie la matiere du point d'intersection.

◆ hit_brdf()

Brdf hit_brdf ( const Hit hit,
const GLTFScene scene,
const std::vector< ImageData > &  textures 
)

evalue les parametres pbr (couleur, metal, rugosite) de la matiere au point d'intersection, en fonction des textures aussi, si necessaire

Definition at line 548 of file tuto_bvh2_gltf_brdf.cpp.

549 {
550  // recupere la description de la matiere...
551  const GLTFMaterial& material= hit_material(hit, scene);
552 
553  // et les coordonnees de textures, si elles existent...
554  vec2 texcoords= vec2(.5, .5);
555  bool use_texture= has_texcoords(hit, scene) && textures.size();
556  if(use_texture)
557  texcoords= hit_texcoords(hit, scene);
558 
559  Color color= material.color;
560  if(use_texture && material.color_texture != -1 && material.color_texture < int(textures.size()))
561  color= color * sample_texture(texcoords, textures[material.color_texture]);
562 
563  float metallic= material.metallic;
564  float roughness= material.roughness;
565  if(use_texture && material.metallic_roughness_texture != -1 && material.metallic_roughness_texture < int(textures.size()))
566  {
567  Color texel= sample_texture(texcoords, textures[material.metallic_roughness_texture]);
568  metallic= metallic * texel.b;
569  roughness= roughness * texel.g;
570  }
571 
572  float transmission= material.transmission;
573  if(use_texture && material.transmission_texture != -1 && material.transmission_texture < int(textures.size()))
574  transmission= transmission * sample_texture(texcoords, textures[material.transmission_texture]).r;
575 
576  Brdf brdf;
577  {
578  if(has_normals(hit, scene))
579  // normale interpolee
580  brdf.n= hit_normal(hit, scene);
581  else
582  // normale geometrique du triangle
583  brdf.n= triangle_normal(hit, scene);
584 
585  brdf.diffuse= (1 - metallic) * color;
586  brdf.F0= (1 - metallic) * Color(0.04) + metallic * color;
587  // todo utiliser material.ior a la place de 0.04, si metal==0 et ior != 0
588  // todo utiliser material.specular a la place de F0, si metal==0 et specular != black
589  brdf.emission= material.emission;
590  brdf.metallic= metallic;
591  brdf.alpha= roughness * roughness;
592  brdf.transmission= transmission;
593  }
594 
595  return brdf;
596 }
float transmission
transmission, transparent ou pas (= 0)
Definition: gltf.h:64
int color_texture
indice de la texture ou -1. cf read_gltf_images() pour charger les textures dans le bon ordre....
Definition: gltf.h:73
float roughness
rugosite de la micro surface.
Definition: gltf.h:63
int metallic_roughness_texture
indice de la texture ou -1. les valeurs RGB representent les parametres du modele : B= metallic,...
Definition: gltf.h:74
Color emission
emission pour les sources de lumieres ou pas (= noir).
Definition: gltf.h:61
int transmission_texture
indice de la texture ou -1.
Definition: gltf.h:78
float metallic
metallic / dielectrique.
Definition: gltf.h:62
Vector triangle_normal(const Hit &hit, const GLTFScene &scene)
normale geometrique du triangle, si necessaire... ie si has_normals(hit, scene) == false....
Color emission
emission pour les sources de lumieres ou pas (= noir).
float alpha
rugosite de la micro surface.
Vector hit_normal(const Hit &hit, const GLTFScene &scene)
renvoie la normale interpolee au point d'intersection dans le repere de la scene.
Color sample_texture(const vec2 &t, const ImageData &texture)
float transmission
transmission, transparent ou pas (= 0)
Color diffuse
color.
bool has_normals(const Hit &hit, const GLTFScene &scene)
verifie la presence des normales par sommet.
bool has_texcoords(const Hit &hit, const GLTFScene &scene)
verifie la presence des coordonnees de texture...
vec2 hit_texcoords(const Hit &hit, const GLTFScene &scene)
renvoie les coordonnees de texture du point d'intersection, suppose que has_texcoords(hit,...
Vector n
normale interpolee du point d'intersection
float metallic
metallic / dielectrique.
Color F0
fresnel.
regroupe tous les parametres de la matiere du point d'intersection.