# HG changeset patch # User John Tsiombikas # Date 1397512777 -10800 # Node ID 252999cd1a3fe2d085c827fb0c689018d764d21c # Parent 859ccadca671e71dbedf9e378d70774f9b175745 added reflection and refraction diff -r 859ccadca671 -r 252999cd1a3f src/main.cc --- a/src/main.cc Mon Apr 14 18:35:37 2014 +0300 +++ b/src/main.cc Tue Apr 15 00:59:37 2014 +0300 @@ -156,7 +156,9 @@ Box *box = new Box; box->mtl.diffuse = Vector3(0.1, 0.4, 1.0); - box->mtl.roughness = 0.9; + box->mtl.specular = Vector3(0.3, 0.6, 1.0); + box->mtl.roughness = 0.2; + box->mtl.reflect = 0.8; box->set_position(Vector3(0, -1.1, 0)); box->set_scaling(Vector3(4, 0.1, 4)); scene->add(box); diff -r 859ccadca671 -r 252999cd1a3f src/raytrace.cc --- a/src/raytrace.cc Mon Apr 14 18:35:37 2014 +0300 +++ b/src/raytrace.cc Tue Apr 15 00:59:37 2014 +0300 @@ -22,17 +22,23 @@ Vector3 shade(const RayHit &hit, int iter) { + const Material &mtl = hit.obj->mtl; + Vector3 pos = hit.ray.origin + hit.ray.dir * hit.dist; Vector3 norm = hit.obj->hit_normal(hit); norm = normalize(transform(normal_matrix(hit.obj->get_matrix()), norm)); Vector3 vdir = -normalize(hit.ray.dir); + float ior = mtl.ior; + + if(dot(norm, hit.ray.dir) > 0.0) { + norm = -norm; + ior = 1.0 / mtl.ior; + } + Vector3 color = scene->get_ambient(); - const Vector3 &kd = hit.obj->mtl.diffuse; - const Vector3 &ks = hit.obj->mtl.specular; - float roughness = hit.obj->mtl.roughness; - + // for each light, calculate local illumination int num_lights = scene->get_light_count(); for(int i=0; iget_light(i); @@ -44,15 +50,29 @@ // if we can see the light, calculate and add its contribution ldir.normalize(); float ndotl = positive(dot(norm, ldir)); - Vector3 diffuse = kd * lcol * ndotl; + Vector3 diffuse = mtl.diffuse * lcol * ndotl; Vector3 hdir = normalize(ldir + vdir); float ndoth = positive(dot(norm, hdir)); - Vector3 specular = ks * lcol * pow(ndoth, roughness * 128.0); + Vector3 specular = mtl.specular * lcol * pow(ndoth, mtl.roughness * 128.0); - color = color + lerp(specular, diffuse, roughness); + color = color + lerp(specular, diffuse, mtl.roughness); } } + if(mtl.reflect > 1e-4 && iter < 6) { + Ray reflray(pos, reflect(vdir, norm)); + + Vector3 rcol = ray_trace(reflray, iter + 1) * mtl.specular * mtl.reflect; + color = color + rcol; + } + + if(mtl.refract > 1e-4 && iter < 6) { + Ray refrray(pos, refract(vdir, norm, ior)); + + Vector3 rcol = ray_trace(refrray, iter + 1) * mtl.specular * mtl.refract; + color = color + rcol; + } + return color; } diff -r 859ccadca671 -r 252999cd1a3f src/vmath.h --- a/src/vmath.h Mon Apr 14 18:35:37 2014 +0300 +++ b/src/vmath.h Tue Apr 15 00:59:37 2014 +0300 @@ -97,6 +97,25 @@ a.z + (b.z - a.z) * t); } +inline Vector3 reflect(const Vector3 &v, const Vector3 &n) +{ + float vdotn = dot(v, n); + return n * vdotn * 2.0 - v; +} + +inline Vector3 refract(const Vector3 &v, const Vector3 &n, float ior) +{ + float cos_inc = dot(v, -n); + float radical = 1.0 + ior * ior * (cos_inc * cos_inc - 1.0); + + if(radical < 0.0) { // total internal reflection + return -reflect(v, n); + } + + float beta = ior * cos_inc - sqrt(radical); + return v * ior + n * beta; +} + // ---- Vector4 ---- class Vector4 {