rayzor
view src/raytrace.cc @ 18:859ccadca671
portability fixes
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 14 Apr 2014 18:35:37 +0300 |
parents | |
children | 252999cd1a3f |
line source
1 #include <assert.h>
2 #include <float.h>
3 #include "raytrace.h"
4 #include "rayzor.h"
5 #include "scene.h"
6 #include "logger.h"
8 Vector3 ray_trace(const Ray &ray, int iter)
9 {
10 RayHit hit;
11 if(!scene->intersect(ray, &hit)) {
12 return scene->get_background(ray);
13 }
15 return shade(hit, iter);
16 }
18 static inline float positive(float x)
19 {
20 return x < 0.0f ? 0.0f : x;
21 }
23 Vector3 shade(const RayHit &hit, int iter)
24 {
25 Vector3 pos = hit.ray.origin + hit.ray.dir * hit.dist;
26 Vector3 norm = hit.obj->hit_normal(hit);
27 norm = normalize(transform(normal_matrix(hit.obj->get_matrix()), norm));
28 Vector3 vdir = -normalize(hit.ray.dir);
30 Vector3 color = scene->get_ambient();
32 const Vector3 &kd = hit.obj->mtl.diffuse;
33 const Vector3 &ks = hit.obj->mtl.specular;
34 float roughness = hit.obj->mtl.roughness;
36 int num_lights = scene->get_light_count();
37 for(int i=0; i<num_lights; i++) {
38 const Light *lt = scene->get_light(i);
39 Vector3 ldir = lt->get_position() - pos;
40 Vector3 lcol = lt->get_color(pos);
42 RayHit hit;
43 if(!scene->intersect(Ray(pos, ldir), &hit) || hit.dist > 1.0) {
44 // if we can see the light, calculate and add its contribution
45 ldir.normalize();
46 float ndotl = positive(dot(norm, ldir));
47 Vector3 diffuse = kd * lcol * ndotl;
49 Vector3 hdir = normalize(ldir + vdir);
50 float ndoth = positive(dot(norm, hdir));
51 Vector3 specular = ks * lcol * pow(ndoth, roughness * 128.0);
53 color = color + lerp(specular, diffuse, roughness);
54 }
55 }
57 return color;
58 }