rayzor

changeset 19:252999cd1a3f

added reflection and refraction
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 15 Apr 2014 00:59:37 +0300
parents 859ccadca671
children 6b11a3f8706e
files src/main.cc src/raytrace.cc src/vmath.h
diffstat 3 files changed, 49 insertions(+), 8 deletions(-) [+]
line diff
     1.1 --- a/src/main.cc	Mon Apr 14 18:35:37 2014 +0300
     1.2 +++ b/src/main.cc	Tue Apr 15 00:59:37 2014 +0300
     1.3 @@ -156,7 +156,9 @@
     1.4  
     1.5  	Box *box = new Box;
     1.6  	box->mtl.diffuse = Vector3(0.1, 0.4, 1.0);
     1.7 -	box->mtl.roughness = 0.9;
     1.8 +	box->mtl.specular = Vector3(0.3, 0.6, 1.0);
     1.9 +	box->mtl.roughness = 0.2;
    1.10 +	box->mtl.reflect = 0.8;
    1.11  	box->set_position(Vector3(0, -1.1, 0));
    1.12  	box->set_scaling(Vector3(4, 0.1, 4));
    1.13  	scene->add(box);
     2.1 --- a/src/raytrace.cc	Mon Apr 14 18:35:37 2014 +0300
     2.2 +++ b/src/raytrace.cc	Tue Apr 15 00:59:37 2014 +0300
     2.3 @@ -22,17 +22,23 @@
     2.4  
     2.5  Vector3 shade(const RayHit &hit, int iter)
     2.6  {
     2.7 +	const Material &mtl = hit.obj->mtl;
     2.8 +
     2.9  	Vector3 pos = hit.ray.origin + hit.ray.dir * hit.dist;
    2.10  	Vector3 norm = hit.obj->hit_normal(hit);
    2.11  	norm = normalize(transform(normal_matrix(hit.obj->get_matrix()), norm));
    2.12  	Vector3 vdir = -normalize(hit.ray.dir);
    2.13  
    2.14 +	float ior = mtl.ior;
    2.15 +
    2.16 +	if(dot(norm, hit.ray.dir) > 0.0) {
    2.17 +		norm = -norm;
    2.18 +		ior = 1.0 / mtl.ior;
    2.19 +	}
    2.20 +
    2.21  	Vector3 color = scene->get_ambient();
    2.22  
    2.23 -	const Vector3 &kd = hit.obj->mtl.diffuse;
    2.24 -	const Vector3 &ks = hit.obj->mtl.specular;
    2.25 -	float roughness = hit.obj->mtl.roughness;
    2.26 -
    2.27 +	// for each light, calculate local illumination
    2.28  	int num_lights = scene->get_light_count();
    2.29  	for(int i=0; i<num_lights; i++) {
    2.30  		const Light *lt = scene->get_light(i);
    2.31 @@ -44,15 +50,29 @@
    2.32  			// if we can see the light, calculate and add its contribution
    2.33  			ldir.normalize();
    2.34  			float ndotl = positive(dot(norm, ldir));
    2.35 -			Vector3 diffuse = kd * lcol * ndotl;
    2.36 +			Vector3 diffuse = mtl.diffuse * lcol * ndotl;
    2.37  
    2.38  			Vector3 hdir = normalize(ldir + vdir);
    2.39  			float ndoth = positive(dot(norm, hdir));
    2.40 -			Vector3 specular = ks * lcol * pow(ndoth, roughness * 128.0);
    2.41 +			Vector3 specular = mtl.specular * lcol * pow(ndoth, mtl.roughness * 128.0);
    2.42  
    2.43 -			color = color + lerp(specular, diffuse, roughness);
    2.44 +			color = color + lerp(specular, diffuse, mtl.roughness);
    2.45  		}
    2.46  	}
    2.47  
    2.48 +	if(mtl.reflect > 1e-4 && iter < 6) {
    2.49 +		Ray reflray(pos, reflect(vdir, norm));
    2.50 +
    2.51 +		Vector3 rcol = ray_trace(reflray, iter + 1) * mtl.specular * mtl.reflect;
    2.52 +		color = color + rcol;
    2.53 +	}
    2.54 +
    2.55 +	if(mtl.refract > 1e-4 && iter < 6) {
    2.56 +		Ray refrray(pos, refract(vdir, norm,  ior));
    2.57 +
    2.58 +		Vector3 rcol = ray_trace(refrray, iter + 1) * mtl.specular * mtl.refract;
    2.59 +		color = color + rcol;
    2.60 +	}
    2.61 +
    2.62  	return color;
    2.63  }
     3.1 --- a/src/vmath.h	Mon Apr 14 18:35:37 2014 +0300
     3.2 +++ b/src/vmath.h	Tue Apr 15 00:59:37 2014 +0300
     3.3 @@ -97,6 +97,25 @@
     3.4  			a.z + (b.z - a.z) * t);
     3.5  }
     3.6  
     3.7 +inline Vector3 reflect(const Vector3 &v, const Vector3 &n)
     3.8 +{
     3.9 +	float vdotn = dot(v, n);
    3.10 +	return n * vdotn * 2.0 - v;
    3.11 +}
    3.12 +
    3.13 +inline Vector3 refract(const Vector3 &v, const Vector3 &n, float ior)
    3.14 +{
    3.15 +	float cos_inc = dot(v, -n);
    3.16 +	float radical = 1.0 + ior * ior * (cos_inc * cos_inc - 1.0);
    3.17 +
    3.18 +	if(radical < 0.0) {	// total internal reflection
    3.19 +		return -reflect(v, n);
    3.20 +	}
    3.21 +
    3.22 +	float beta = ior * cos_inc - sqrt(radical);
    3.23 +	return v * ior + n * beta;
    3.24 +}
    3.25 +
    3.26  // ---- Vector4 ----
    3.27  
    3.28  class Vector4 {