rayzor

annotate src/raytrace.cc @ 17:79609d482762

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