rayzor

annotate src/raytrace.cc @ 22:5380ff64e83f

minor changes from dos, and line endings cleanup
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 02 May 2014 14:32:58 +0300
parents 252999cd1a3f
children
rev   line source
nuclear@22 1 #include <assert.h>
nuclear@22 2 #include <float.h>
nuclear@22 3 #include "raytrace.h"
nuclear@22 4 #include "rayzor.h"
nuclear@22 5 #include "scene.h"
nuclear@22 6 #include "logger.h"
nuclear@22 7
nuclear@22 8 Vector3 ray_trace(const Ray &ray, int iter)
nuclear@22 9 {
nuclear@22 10 RayHit hit;
nuclear@22 11 if(!scene->intersect(ray, &hit)) {
nuclear@22 12 return scene->get_background(ray);
nuclear@22 13 }
nuclear@22 14
nuclear@22 15 return shade(hit, iter);
nuclear@22 16 }
nuclear@22 17
nuclear@22 18 static inline float positive(float x)
nuclear@22 19 {
nuclear@22 20 return x < 0.0f ? 0.0f : x;
nuclear@22 21 }
nuclear@22 22
nuclear@22 23 Vector3 shade(const RayHit &hit, int iter)
nuclear@22 24 {
nuclear@22 25 const Material &mtl = hit.obj->mtl;
nuclear@22 26
nuclear@22 27 Vector3 pos = hit.ray.origin + hit.ray.dir * hit.dist;
nuclear@22 28 Vector3 norm = hit.obj->hit_normal(hit);
nuclear@22 29 norm = normalize(transform(normal_matrix(hit.obj->get_matrix()), norm));
nuclear@22 30 Vector3 vdir = -normalize(hit.ray.dir);
nuclear@22 31
nuclear@22 32 float ior = mtl.ior;
nuclear@22 33
nuclear@22 34 if(dot(norm, hit.ray.dir) > 0.0) {
nuclear@22 35 norm = -norm;
nuclear@22 36 ior = 1.0 / mtl.ior;
nuclear@22 37 }
nuclear@22 38
nuclear@22 39 Vector3 color = scene->get_ambient();
nuclear@22 40
nuclear@22 41 // for each light, calculate local illumination
nuclear@22 42 int num_lights = scene->get_light_count();
nuclear@22 43 for(int i=0; i<num_lights; i++) {
nuclear@22 44 const Light *lt = scene->get_light(i);
nuclear@22 45 Vector3 ldir = lt->get_position() - pos;
nuclear@22 46 Vector3 lcol = lt->get_color(pos);
nuclear@22 47
nuclear@22 48 RayHit hit;
nuclear@22 49 if(!scene->intersect(Ray(pos, ldir), &hit) || hit.dist > 1.0) {
nuclear@22 50 // if we can see the light, calculate and add its contribution
nuclear@22 51 ldir.normalize();
nuclear@22 52 float ndotl = positive(dot(norm, ldir));
nuclear@22 53 Vector3 diffuse = mtl.diffuse * lcol * ndotl;
nuclear@22 54
nuclear@22 55 Vector3 hdir = normalize(ldir + vdir);
nuclear@22 56 float ndoth = positive(dot(norm, hdir));
nuclear@22 57 Vector3 specular = mtl.specular * lcol * pow(ndoth, mtl.roughness * 128.0);
nuclear@22 58
nuclear@22 59 color = color + lerp(specular, diffuse, mtl.roughness);
nuclear@22 60 }
nuclear@22 61 }
nuclear@22 62
nuclear@22 63 if(mtl.reflect > 1e-4 && iter < 6) {
nuclear@22 64 Ray reflray(pos, reflect(vdir, norm));
nuclear@22 65
nuclear@22 66 Vector3 rcol = ray_trace(reflray, iter + 1) * mtl.specular * mtl.reflect;
nuclear@22 67 color = color + rcol;
nuclear@22 68 }
nuclear@22 69
nuclear@22 70 if(mtl.refract > 1e-4 && iter < 6) {
nuclear@22 71 Ray refrray(pos, refract(vdir, norm, ior));
nuclear@22 72
nuclear@22 73 Vector3 rcol = ray_trace(refrray, iter + 1) * mtl.specular * mtl.refract;
nuclear@22 74 color = color + rcol;
nuclear@22 75 }
nuclear@22 76
nuclear@22 77 return color;
nuclear@22 78 }