erebus
diff liberebus/src/rt.cc @ 43:ed18af9da8f7
first attempt at separating direct from indirect failed miserably
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 11 Jun 2014 16:38:11 +0300 |
parents | 5e27c85e79ca |
children | c4d48a21bc4a |
line diff
1.1 --- a/liberebus/src/rt.cc Tue Jun 10 16:15:08 2014 +0300 1.2 +++ b/liberebus/src/rt.cc Wed Jun 11 16:38:11 2014 +0300 1.3 @@ -9,6 +9,11 @@ 1.4 return Color(1, 0, 0); 1.5 } 1.6 1.7 + if(iter > erb_getopti(ctx, ERB_OPT_MAX_ITER) || ray.energy < 0.0001) { 1.8 + //return Color(1, 0, 1); 1.9 + return Color(0, 0, 0); 1.10 + } 1.11 + 1.12 RayHit hit; 1.13 if(!(scn->intersect(ray, &hit))) { 1.14 return scn->get_env_color(ray); 1.15 @@ -20,7 +25,6 @@ 1.16 Color shade(struct erebus *ctx, const RayHit &hit, int iter) 1.17 { 1.18 assert(hit.obj->get_type() == ObjType::geom); 1.19 - int max_iter = erb_getopti(ctx, ERB_OPT_MAX_ITER); 1.20 const Scene *scn = ctx->scn; 1.21 const GeomObject *obj = (const GeomObject*)hit.obj; 1.22 const Material *mtl = &obj->mtl; 1.23 @@ -28,6 +32,8 @@ 1.24 const Ray &ray = hit.world_ray; 1.25 //bool entering = true; 1.26 1.27 + Vector3 pos = ray.origin + ray.dir * hit.dist; 1.28 + 1.29 Vector3 norm = hit.calc_normal(); 1.30 if(dot_product(ray.dir, norm) > 0.0) { 1.31 //entering = false; 1.32 @@ -39,15 +45,73 @@ 1.33 1.34 Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y); 1.35 Color specular = mtl->get_attrib_color("specular", texcoords.x, texcoords.y); 1.36 - Color res = mtl->get_attrib_color("emissive", texcoords.x, texcoords.y) + 1.37 - color * scn->get_env().ambient; 1.38 + Color res = color * scn->get_env().ambient; 1.39 float shininess = mtl->get_attrib_value("shininess"); 1.40 1.41 + res += mtl->get_attrib_color("emissive", texcoords.x, texcoords.y); 1.42 + 1.43 + /* 1.44 + // calculate direct illumination 1.45 + Vector3 vdir = -ray.dir.normalized(); 1.46 + std::list<ObjectInstance> lights = scn->gen_light_list(); 1.47 + auto it = lights.cbegin(); 1.48 + while(it != lights.cend()) { 1.49 + const ObjectInstance &inst = *it++; 1.50 + GeomObject *light = (GeomObject*)inst.obj; 1.51 + SceneNode *light_node = inst.node; 1.52 + 1.53 + if(obj == light) { 1.54 + // don't try to get illumination from ourselves 1.55 + continue; 1.56 + } 1.57 + 1.58 + const Matrix4x4 &xform = light_node->get_matrix(); 1.59 + const Matrix4x4 &inv_xform = light_node->get_inv_matrix(); 1.60 + Vector3 spt = light->gen_surface_point().transformed(xform); 1.61 + 1.62 + Vector3 ldir = spt - pos; 1.63 + if(dot_product(ldir, norm) < 0.0) { 1.64 + continue; 1.65 + } 1.66 + Ray shadow_ray{pos, ldir}; 1.67 + 1.68 + RayHit shadow_hit; 1.69 + shadow_hit.obj = 0; 1.70 + if(scn->intersect(shadow_ray, &shadow_hit) && shadow_hit.obj != light && 1.71 + shadow_hit.dist < 0.99999 && shadow_hit.dist > 1e-5) { 1.72 + // we're in shadow, skip 1.73 + continue; 1.74 + } 1.75 + 1.76 + if(!shadow_hit.obj) { 1.77 + shadow_hit.obj = light; 1.78 + shadow_hit.dist = 1.0; 1.79 + shadow_hit.world_ray = shadow_ray; 1.80 + shadow_hit.local_ray = shadow_ray.transformed(inv_xform); 1.81 + shadow_hit.node = inst.node; 1.82 + } 1.83 + 1.84 + Vector2 tc = shadow_hit.calc_texcoords(); 1.85 + Color lcol = light->mtl.get_attrib_color("emissive", tc.x, tc.y); 1.86 + 1.87 + ldir.normalize(); 1.88 + norm.normalize(); 1.89 + float ndotl = dot_product(ldir, norm); 1.90 + 1.91 + Vector3 refl = ldir.reflection(norm); 1.92 + float vdotr = dot_product(vdir, refl); 1.93 + 1.94 + Color direct = ray.energy * lcol * (color * ndotl);// + specular * pow(vdotr, shininess)); 1.95 + assert(direct.x >= 0.0 && direct.y >= 0.0 && direct.z >= 0.0); 1.96 + res += direct; 1.97 + } 1.98 + */ 1.99 + 1.100 Vector3 sample_dir; 1.101 - float prob = brdf->sample(SurfaceGeometry(norm), -hit.world_ray.dir, &sample_dir); 1.102 - if(iter < max_iter && randf() <= prob && ray.energy * prob > 0.001) { 1.103 + float prob = brdf->sample(SurfaceGeometry(norm), -ray.dir, &sample_dir); 1.104 + if(randf() <= prob) { 1.105 Ray sample_ray; 1.106 - sample_ray.origin = ray.origin + ray.dir * hit.dist; 1.107 + sample_ray.origin = pos; 1.108 sample_ray.dir = sample_dir; 1.109 sample_ray.energy = ray.energy * prob; 1.110