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 {