gKit2 light
ray.cpp
1 #include <cstdio>
2 #include <cassert>
3 
4 #include <cmath>
5 #include <algorithm>
6 
7 #include "ray.h"
8 
9 
10 Ray make_ray( const Point& o, const Point& e )
11 {
12  return Ray(o, e);
13 }
14 
15 
16 // cf https://www.bramz.net/data/writings/reflection_transmission.pdf
17 
18 Ray reflect( const Ray& ray, const Point& p, const Vector& n )
19 {
20  Vector nn= n;
21  // la normale est orientee vers l'exterieur de l'objet et le rayon est oriente vers l'objet
22  if(dot(ray.direction, n) > 0)
23  // le rayon est a l'interieur de l'objet, retourner la normale
24  nn= -n;
25 
26  Ray r;
27  r.origin= p + 0.001f * nn;
28  r.direction= ray.direction - 2 * dot(ray.direction, nn) * nn;
29  return r;
30 }
31 
32 Ray refract( const Ray& ray, const Point& p, const Vector& n, const float ir )
33 {
34  float n1= 1;
35  float n2= ir;
36  Vector nn= n;
37 
38  float cos_theta= -dot(ray.direction, n);
39  if(cos_theta < 0)
40  {
41  // sortie de l'objet
42  n1= ir;
43  n2= 1;
44  nn= -n;
45  cos_theta= -cos_theta;
46  }
47 
48  float i= n1 / n2;
49  float sin2_theta= i*i * (1.f - cos_theta*cos_theta);
50 
51  Ray t;
52  t.origin= p - 0.001f * nn;
53  if(sin2_theta >= 1.f)
54  // reflexion totale interne, pas de refraction
55  return t;
56 
57  t.direction= i * (ray.direction + cos_theta * nn) - std::sqrt(1.f - sin2_theta) * nn;
58  return t;
59 }
60 
61 bool fresnel_refract( const Ray& ray, const Point& p, const Vector& n, const float ir )
62 {
63  float n1= 1;
64  float n2= ir;
65 
66  float cos_theta= -dot(ray.direction, n);
67  if(cos_theta < 0)
68  {
69  // sortie de l'objet
70  n1= ir;
71  n2= 1;
72  }
73 
74  float i= n1 / n2;
75  float sin2_theta= i*i * (1.f - cos_theta*cos_theta);
76  return (sin2_theta < 1.f);
77 }
78 
79 float fresnel( const Ray& ray, const Point& p, const Vector& n, const float ir )
80 {
81  float n1= 1;
82  float n2= ir;
83 
84  float cos_theta= -dot(ray.direction, n);
85  if(cos_theta < 0)
86  {
87  // sortie de l'objet
88  n1= ir;
89  n2= 1;
90 
91  // verifier que la refraction existe
92  float i= n1 / n2;
93  float sin2_theta= i*i * (1.f - cos_theta*cos_theta);
94  if(sin2_theta > 1.f)
95  // reflexion totale interne, pas de refraction
96  return 1.f;
97 
98  // utiliser la direction refractee
99  cos_theta= std::sqrt(1.f - sin2_theta);
100  }
101 
102  float r0= (n1 - n2) / (n1 + n2);
103  r0= r0 * r0;
104 
105  float c= 1.f - cos_theta;
106  return r0 + (1.f - r0) * c*c*c*c*c;
107 }
representation d'un vecteur 3d.
Definition: vec.h:42
float dot(const Vector &u, const Vector &v)
renvoie le produit scalaire de 2 vecteurs.
Definition: vec.cpp:93
representation d'un rayon.
Definition: ray.h:12
representation d'un point 3d.
Definition: vec.h:19