erebus
changeset 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 | b9294cd6b9dc |
children | a2afaf8af09b |
files | .clang_complete liberebus/src/erebus.cc liberebus/src/geomobj.cc liberebus/src/rt.cc liberebus/src/scene.cc liberebus/src/scene.h test/scene |
diffstat | 7 files changed, 108 insertions(+), 14 deletions(-) [+] |
line diff
1.1 --- a/.clang_complete Tue Jun 10 16:15:08 2014 +0300 1.2 +++ b/.clang_complete Wed Jun 11 16:38:11 2014 +0300 1.3 @@ -1,3 +1,4 @@ 1.4 -std=c++11 1.5 +-Isrc 1.6 -Iliberebus/src 1.7 -I/usr/local/include
2.1 --- a/liberebus/src/erebus.cc Tue Jun 10 16:15:08 2014 +0300 2.2 +++ b/liberebus/src/erebus.cc Wed Jun 11 16:38:11 2014 +0300 2.3 @@ -459,6 +459,8 @@ 2.4 float *accum = ctx->accum.get_pixels() + offs; 2.5 2.6 Ray ray = cam->get_primary_ray(x, y, xsz, ysz, sample); 2.7 + ray.energy = 1.0; 2.8 + 2.9 Color c = ray_trace(ctx, ray, 0); 2.10 accum[0] += c.x; 2.11 accum[1] += c.y; 2.12 @@ -469,5 +471,5 @@ 2.13 pix[0] = pow(accum[0] * inv_samples, ctx->inv_gamma); 2.14 pix[1] = pow(accum[1] * inv_samples, ctx->inv_gamma); 2.15 pix[2] = pow(accum[2] * inv_samples, ctx->inv_gamma); 2.16 - pix[3] = accum[3] * inv_samples; 2.17 + pix[3] = 1.0;//accum[3] * inv_samples; 2.18 }
3.1 --- a/liberebus/src/geomobj.cc Tue Jun 10 16:15:08 2014 +0300 3.2 +++ b/liberebus/src/geomobj.cc Wed Jun 11 16:38:11 2014 +0300 3.3 @@ -52,16 +52,16 @@ 3.4 float c = dot_product(ray.origin, ray.origin) - 1.0; 3.5 3.6 float d = b * b - 4.0 * a * c; 3.7 - if(d < 1e-6) return false; 3.8 + if(d < 1e-5) return false; 3.9 3.10 float sqrt_d = sqrt(d); 3.11 float t0 = (-b + sqrt_d) / (2.0 * a); 3.12 float t1 = (-b - sqrt_d) / (2.0 * a); 3.13 3.14 - if(t0 < 1e-6) t0 = t1; 3.15 - if(t1 < 1e-6) t1 = t0; 3.16 + if(t0 < 1e-5) t0 = t1; 3.17 + if(t1 < 1e-5) t1 = t0; 3.18 float t = t0 < t1 ? t0 : t1; 3.19 - if(t < 1e-6) return false; 3.20 + if(t < 1e-5) return false; 3.21 3.22 if(hit) { 3.23 hit->dist = t; 3.24 @@ -146,8 +146,8 @@ 3.25 tmax = tzmax; 3.26 } 3.27 3.28 - float t = tmin < 1e-4 ? tmax : tmin; 3.29 - if(t >= 1e-4) { 3.30 + float t = tmin < 1e-5 ? tmax : tmin; 3.31 + if(t >= 1e-5) { 3.32 if(hit) { 3.33 hit->obj = this; 3.34 hit->dist = t;
4.1 --- a/liberebus/src/rt.cc Tue Jun 10 16:15:08 2014 +0300 4.2 +++ b/liberebus/src/rt.cc Wed Jun 11 16:38:11 2014 +0300 4.3 @@ -9,6 +9,11 @@ 4.4 return Color(1, 0, 0); 4.5 } 4.6 4.7 + if(iter > erb_getopti(ctx, ERB_OPT_MAX_ITER) || ray.energy < 0.0001) { 4.8 + //return Color(1, 0, 1); 4.9 + return Color(0, 0, 0); 4.10 + } 4.11 + 4.12 RayHit hit; 4.13 if(!(scn->intersect(ray, &hit))) { 4.14 return scn->get_env_color(ray); 4.15 @@ -20,7 +25,6 @@ 4.16 Color shade(struct erebus *ctx, const RayHit &hit, int iter) 4.17 { 4.18 assert(hit.obj->get_type() == ObjType::geom); 4.19 - int max_iter = erb_getopti(ctx, ERB_OPT_MAX_ITER); 4.20 const Scene *scn = ctx->scn; 4.21 const GeomObject *obj = (const GeomObject*)hit.obj; 4.22 const Material *mtl = &obj->mtl; 4.23 @@ -28,6 +32,8 @@ 4.24 const Ray &ray = hit.world_ray; 4.25 //bool entering = true; 4.26 4.27 + Vector3 pos = ray.origin + ray.dir * hit.dist; 4.28 + 4.29 Vector3 norm = hit.calc_normal(); 4.30 if(dot_product(ray.dir, norm) > 0.0) { 4.31 //entering = false; 4.32 @@ -39,15 +45,73 @@ 4.33 4.34 Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y); 4.35 Color specular = mtl->get_attrib_color("specular", texcoords.x, texcoords.y); 4.36 - Color res = mtl->get_attrib_color("emissive", texcoords.x, texcoords.y) + 4.37 - color * scn->get_env().ambient; 4.38 + Color res = color * scn->get_env().ambient; 4.39 float shininess = mtl->get_attrib_value("shininess"); 4.40 4.41 + res += mtl->get_attrib_color("emissive", texcoords.x, texcoords.y); 4.42 + 4.43 + /* 4.44 + // calculate direct illumination 4.45 + Vector3 vdir = -ray.dir.normalized(); 4.46 + std::list<ObjectInstance> lights = scn->gen_light_list(); 4.47 + auto it = lights.cbegin(); 4.48 + while(it != lights.cend()) { 4.49 + const ObjectInstance &inst = *it++; 4.50 + GeomObject *light = (GeomObject*)inst.obj; 4.51 + SceneNode *light_node = inst.node; 4.52 + 4.53 + if(obj == light) { 4.54 + // don't try to get illumination from ourselves 4.55 + continue; 4.56 + } 4.57 + 4.58 + const Matrix4x4 &xform = light_node->get_matrix(); 4.59 + const Matrix4x4 &inv_xform = light_node->get_inv_matrix(); 4.60 + Vector3 spt = light->gen_surface_point().transformed(xform); 4.61 + 4.62 + Vector3 ldir = spt - pos; 4.63 + if(dot_product(ldir, norm) < 0.0) { 4.64 + continue; 4.65 + } 4.66 + Ray shadow_ray{pos, ldir}; 4.67 + 4.68 + RayHit shadow_hit; 4.69 + shadow_hit.obj = 0; 4.70 + if(scn->intersect(shadow_ray, &shadow_hit) && shadow_hit.obj != light && 4.71 + shadow_hit.dist < 0.99999 && shadow_hit.dist > 1e-5) { 4.72 + // we're in shadow, skip 4.73 + continue; 4.74 + } 4.75 + 4.76 + if(!shadow_hit.obj) { 4.77 + shadow_hit.obj = light; 4.78 + shadow_hit.dist = 1.0; 4.79 + shadow_hit.world_ray = shadow_ray; 4.80 + shadow_hit.local_ray = shadow_ray.transformed(inv_xform); 4.81 + shadow_hit.node = inst.node; 4.82 + } 4.83 + 4.84 + Vector2 tc = shadow_hit.calc_texcoords(); 4.85 + Color lcol = light->mtl.get_attrib_color("emissive", tc.x, tc.y); 4.86 + 4.87 + ldir.normalize(); 4.88 + norm.normalize(); 4.89 + float ndotl = dot_product(ldir, norm); 4.90 + 4.91 + Vector3 refl = ldir.reflection(norm); 4.92 + float vdotr = dot_product(vdir, refl); 4.93 + 4.94 + Color direct = ray.energy * lcol * (color * ndotl);// + specular * pow(vdotr, shininess)); 4.95 + assert(direct.x >= 0.0 && direct.y >= 0.0 && direct.z >= 0.0); 4.96 + res += direct; 4.97 + } 4.98 + */ 4.99 + 4.100 Vector3 sample_dir; 4.101 - float prob = brdf->sample(SurfaceGeometry(norm), -hit.world_ray.dir, &sample_dir); 4.102 - if(iter < max_iter && randf() <= prob && ray.energy * prob > 0.001) { 4.103 + float prob = brdf->sample(SurfaceGeometry(norm), -ray.dir, &sample_dir); 4.104 + if(randf() <= prob) { 4.105 Ray sample_ray; 4.106 - sample_ray.origin = ray.origin + ray.dir * hit.dist; 4.107 + sample_ray.origin = pos; 4.108 sample_ray.dir = sample_dir; 4.109 sample_ray.energy = ray.energy * prob; 4.110
5.1 --- a/liberebus/src/scene.cc Tue Jun 10 16:15:08 2014 +0300 5.2 +++ b/liberebus/src/scene.cc Wed Jun 11 16:38:11 2014 +0300 5.3 @@ -111,6 +111,31 @@ 5.4 return active_cam; 5.5 } 5.6 5.7 +std::list<ObjectInstance> Scene::gen_light_list() const 5.8 +{ 5.9 + std::list<ObjectInstance> list; 5.10 + 5.11 + for(auto n : nodes) { 5.12 + int nobj = n->get_num_objects(); 5.13 + for(int i=0; i<nobj; i++) { 5.14 + Object *o = n->get_object(i); 5.15 + if(o->get_type() != ObjType::geom) { 5.16 + continue; 5.17 + } 5.18 + GeomObject *go = (GeomObject*)o; 5.19 + 5.20 + if(go->mtl.get_attrib_value("emissive") > 0.0) { 5.21 + ObjectInstance inst; 5.22 + inst.obj = go; 5.23 + inst.node = n; 5.24 + 5.25 + list.push_back(inst); 5.26 + } 5.27 + } 5.28 + } 5.29 + return std::move(list); 5.30 +} 5.31 + 5.32 void Scene::update(long msec) 5.33 { 5.34 root->update(msec);
6.1 --- a/liberebus/src/scene.h Tue Jun 10 16:15:08 2014 +0300 6.2 +++ b/liberebus/src/scene.h Wed Jun 11 16:38:11 2014 +0300 6.3 @@ -56,6 +56,8 @@ 6.4 void use_camera(Camera *cam); 6.5 Camera *get_active_camera() const; 6.6 6.7 + std::list<ObjectInstance> gen_light_list() const; 6.8 + 6.9 void update(long msec = 0); 6.10 6.11 bool intersect(const Ray &ray, RayHit *hit) const;
7.1 --- a/test/scene Tue Jun 10 16:15:08 2014 +0300 7.2 +++ b/test/scene Wed Jun 11 16:38:11 2014 +0300 7.3 @@ -9,6 +9,6 @@ 7.4 -brdf mirror -brdf-weight 0.7 7.5 box -position 0 3.75 0 -scaling 20 10 20 -diffuse 1.0 1.0 1.0 -brdf lambert 7.6 7.7 -box -position 0 4 0 -scaling 3 0.1 3 -emissive 8 8 8 7.8 +box -position 0 4 0 -scaling 3 0.1 3 -emissive 6 6 6 7.9 7.10 camera -position 0 3 -6 -target 0 0 0