41 m.diffuse= make_color(1, 1, 1);
54 m.diffuse= make_color(1, 0, 1);
73 Sphere(
const Point& c,
const float r,
const Color& cc ) : material(make_diffuse(cc)), model(make_identity()), center(c), radius(r) {}
74 Sphere(
const Point& c,
const float r,
const Material& m ) : material(m), model(make_identity()), center(c), radius(r) {}
78 bool intersect(
const Sphere& sphere,
const Ray& ray,
float& hit )
80 Point center= transform(sphere.model, sphere.center);
82 float b=
dot(oc, ray.direction);
83 float c=
dot(oc, oc) - sphere.radius*sphere.radius;
86 if(h < 0.0)
return false;
94 if(t1 <= 0 && t2 <= 0)
97 else if(t1 > 0 && t2 > 0)
100 t1= std::max(t1, t2);
131 Plane(
const Point& a,
const Vector& n,
const Color& c= make_white() ) : material(make_diffuse(c)), anchor(a), normal(n) {}
136 bool intersect(
const Plane& plane,
const Ray& ray,
float &hit )
138 float t=
dot(plane.anchor - ray.origin, plane.normal) /
dot(ray.direction, plane.normal);
139 if(t < 0)
return false;
151 std::vector<Plane> planes;
152 std::vector<Sphere> spheres;
155 bool intersect(
const Ray& ray,
const float tmax,
Hit& hit,
Material& m )
159 for(
unsigned int i= 0; i < (
unsigned int) planes.size(); i++)
160 if(intersect(planes[i], ray, t))
163 hit.
p= ray.origin + t * ray.direction;
164 hit.
n= planes[i].normal;
165 hit.
color= planes[i].material.diffuse;
169 Vector p= make_vector(planes[i].anchor, hit.
p);
170 int x= std::abs(std::floor(p.x));
171 int y= std::abs(std::floor(p.y));
172 int z= std::abs(std::floor(p.z));
173 Color color= ((x%2) ^ (z%2)) ? planes[i].material.diffuse : make_white();
175 m= make_diffuse(color);
179 for(
unsigned int i= 0; i < (
unsigned int) spheres.size(); i++)
180 if(intersect(spheres[i], ray, t))
183 hit.
p= ray.origin + t * ray.direction;
184 hit.
n=
normalize(make_vector(transform(spheres[i].model, spheres[i].center), hit.
p));
185 m= spheres[i].material;
194 Ray ray= make_ray(p + .001f * n, l);
197 intersect(ray,
distance(p + .001f * n, l), hit, m);
199 return hit.hit ? 0.f : 1.f;
203 int main(
int argc,
char **argv )
208 planes.push_back(
Plane(make_point(0, 0, 0),
normalize(make_vector(0, 1, 0)), make_red()) );
209 planes.push_back(
Plane(make_point(0, 0, 16),
normalize(make_vector(0, 0, -1)), make_red()) );
210 planes.push_back(
Plane(make_point(0, 0, -16),
normalize(make_vector(0, 0, 1)), make_white()) );
212 spheres.push_back(
Sphere(make_point(0, 0, 0), 1, make_white()) );
214 spheres.push_back(
Sphere(make_point(1, 0, 0), 0.5f, make_red()) );
215 spheres.push_back(
Sphere(make_point(0, 1, 0), 0.5f, make_green()) );
216 spheres.push_back(
Sphere(make_point(0, 0, 1), 0.5f, make_blue()) );
219 for(
int i= 0; i < 10; i++)
221 float x= drand48() * 20 - 10;
222 float y= drand48() * 5 + 2;
223 float z= drand48() * 20 - 10;
224 float r= drand48() * 2 + .25f;
225 spheres.push_back(
Sphere(make_point(x, y, z), r, make_glass(make_white(), 1.3f)) );
229 Point light= make_point(10, 20, -2);
230 Color emission= make_white() * 500;
233 Orbiter camera= make_orbiter_lookat( make_point(0, 0, 0), 15 );
234 orbiter_rotation(camera, 0, 45);
237 Image image(1024, 640);
241 Point o= orbiter_position(camera);
242 orbiter_image_frame(camera, image.width(), image.height(), 0, 45, d0, dx, dy);
244 #pragma omp parallel for schedule(dynamic, 16)
245 for(
int y= 0; y < image.height(); y++)
246 for(
int x= 0; x < image.width(); x++)
248 Color pixel= make_black();
250 const int samples= 16;
251 for(
int s= 0; s < samples; s++)
253 Point e= d0 + ((float) x + drand48() - 0.5f) * dx + ((
float) y + drand48() - 0.5f) * dy;
254 Ray ray= make_ray(o, e);
258 if(intersect(ray, FLT_MAX, hit, m))
260 Color color= make_black();
264 Ray mray= reflect(ray, hit.p, hit.n);
267 if(intersect(mray, FLT_MAX, mhit, mm))
270 float cos_theta= std::max( 0.f,
dot(
normalize(make_vector(mhit.
p, light)), mhit.
n));
271 color= color + m.specular * fresnel(ray, hit.p, hit.n, m.ir) * emission /
distance2(mhit.
p, light) * mm.diffuse * shadow(mhit.
p, mhit.
n, light) * cos_theta;
274 color= color + m.specular * fresnel(ray, hit.p, hit.n, m.ir) * make_color(1, 1, 0) *2;
280 if(fresnel_refract(ray, hit.p, hit.n, m.ir))
282 Ray iray= refract(ray, hit.p, hit.n, m.ir);
285 if(intersect(iray, FLT_MAX, ihit, im))
288 if(fresnel_refract(iray, ihit.
p, ihit.
n, im.
ir))
290 Ray oray= refract(iray, ihit.
p, ihit.
n, im.
ir);
293 if(intersect(oray, FLT_MAX, ohit, om))
296 float cos_theta= std::max( 0.f,
dot(
normalize(make_vector(ohit.
p, light)), ohit.
n));
297 color= color + m.specular * (1.f - fresnel(ray, hit.p, hit.n, m.ir)) * im.specular * (1.f - fresnel(iray, ihit.
p, ihit.
n, im.
ir))
298 * emission /
distance2(ohit.
p, light) * om.diffuse * shadow(ohit.
p, ohit.
n, light) * cos_theta;
308 float cos_theta= std::max( 0.f,
dot(
normalize(make_vector(hit.p, light)), hit.n));
309 color= emission /
distance2(hit.p, light) * m.diffuse * shadow(hit.p, hit.n, light) * cos_theta;
312 pixel= pixel + color;
316 image(x, y)=
Color(pixel / (
float) samples, 1);
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet...
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
float kd
ks * diffuse + ks * speculaire, kd + ks == 1
bool reflect
specualr reflect
representation d'une couleur (rgba) transparente ou opaque.
Color color
couleur de la surface au point d'intersection
representation d'une matiere
representation d'un vecteur 3d.
float dot(const Vector &u, const Vector &v)
renvoie le produit scalaire de 2 vecteurs.
float t
abscisse : p= o + t.d
representation d'un point d'intersection.
Vector n
normale de la surface au point d'intersection
bool refract
specualr refract
int write_image(const Image &image, const char *filename)
enregistre une image dans un fichier png.
representation d'un rayon.
representation d'une image.
float distance(const Point &a, const Point &b)
renvoie la distance etre 2 points.
representation d'un point 3d.
float ns
exposant blinn phong
Point center(const Point &a, const Point &b)
renvoie le milieu du segment ab.
representation d'une sphere.
float ir
indice de refraction
float distance2(const Point &a, const Point &b)
renvoie le carre de la distance etre 2 points.
representation d'un plan. point + normale.