rayzor

diff 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
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/raytrace.cc	Mon Apr 14 07:34:45 2014 +0300
     1.3 @@ -0,0 +1,58 @@
     1.4 +#include <assert.h>
     1.5 +#include <float.h>
     1.6 +#include "raytrace.h"
     1.7 +#include "rayzor.h"
     1.8 +#include "scene.h"
     1.9 +#include "logger.h"
    1.10 +
    1.11 +Vector3 ray_trace(const Ray &ray, int iter)
    1.12 +{
    1.13 +	RayHit hit;
    1.14 +	if(!scene->intersect(ray, &hit)) {
    1.15 +		return scene->get_background(ray);
    1.16 +	}
    1.17 +
    1.18 +	return shade(hit, iter);
    1.19 +}
    1.20 +
    1.21 +static inline float positive(float x)
    1.22 +{
    1.23 +	return x < 0.0f ? 0.0f : x;
    1.24 +}
    1.25 +
    1.26 +Vector3 shade(const RayHit &hit, int iter)
    1.27 +{
    1.28 +	Vector3 pos = hit.ray.origin + hit.ray.dir * hit.dist;
    1.29 +	Vector3 norm = hit.obj->hit_normal(hit);
    1.30 +	norm = normalize(transform(normal_matrix(hit.obj->get_matrix()), norm));
    1.31 +	Vector3 vdir = -normalize(hit.ray.dir);
    1.32 +
    1.33 +	Vector3 color = scene->get_ambient();
    1.34 +
    1.35 +	const Vector3 &kd = hit.obj->mtl.diffuse;
    1.36 +	const Vector3 &ks = hit.obj->mtl.specular;
    1.37 +	float roughness = hit.obj->mtl.roughness;
    1.38 +
    1.39 +	int num_lights = scene->get_light_count();
    1.40 +	for(int i=0; i<num_lights; i++) {
    1.41 +		const Light *lt = scene->get_light(i);
    1.42 +		Vector3 ldir = lt->get_position() - pos;
    1.43 +		Vector3 lcol = lt->get_color(pos);
    1.44 +
    1.45 +		RayHit hit;
    1.46 +		if(!scene->intersect(Ray(pos, ldir), &hit) || hit.dist > 1.0) {
    1.47 +			// if we can see the light, calculate and add its contribution
    1.48 +			ldir.normalize();
    1.49 +			float ndotl = positive(dot(norm, ldir));
    1.50 +			Vector3 diffuse = kd * lcol * ndotl;
    1.51 +
    1.52 +			Vector3 hdir = normalize(ldir + vdir);
    1.53 +			float ndoth = positive(dot(norm, hdir));
    1.54 +			Vector3 specular = ks * lcol * pow(ndoth, roughness * 128.0);
    1.55 +
    1.56 +			color = color + lerp(specular, diffuse, roughness);
    1.57 +		}
    1.58 +	}
    1.59 +
    1.60 +	return color;
    1.61 +}