# HG changeset patch # User John Tsiombikas # Date 1402493891 -10800 # Node ID ed18af9da8f786fe01e408322d364c179b2975d7 # Parent b9294cd6b9dc24996969a9953b131ec1b47bec21 first attempt at separating direct from indirect failed miserably diff -r b9294cd6b9dc -r ed18af9da8f7 .clang_complete --- a/.clang_complete Tue Jun 10 16:15:08 2014 +0300 +++ b/.clang_complete Wed Jun 11 16:38:11 2014 +0300 @@ -1,3 +1,4 @@ -std=c++11 +-Isrc -Iliberebus/src -I/usr/local/include diff -r b9294cd6b9dc -r ed18af9da8f7 liberebus/src/erebus.cc --- a/liberebus/src/erebus.cc Tue Jun 10 16:15:08 2014 +0300 +++ b/liberebus/src/erebus.cc Wed Jun 11 16:38:11 2014 +0300 @@ -459,6 +459,8 @@ float *accum = ctx->accum.get_pixels() + offs; Ray ray = cam->get_primary_ray(x, y, xsz, ysz, sample); + ray.energy = 1.0; + Color c = ray_trace(ctx, ray, 0); accum[0] += c.x; accum[1] += c.y; @@ -469,5 +471,5 @@ pix[0] = pow(accum[0] * inv_samples, ctx->inv_gamma); pix[1] = pow(accum[1] * inv_samples, ctx->inv_gamma); pix[2] = pow(accum[2] * inv_samples, ctx->inv_gamma); - pix[3] = accum[3] * inv_samples; + pix[3] = 1.0;//accum[3] * inv_samples; } diff -r b9294cd6b9dc -r ed18af9da8f7 liberebus/src/geomobj.cc --- a/liberebus/src/geomobj.cc Tue Jun 10 16:15:08 2014 +0300 +++ b/liberebus/src/geomobj.cc Wed Jun 11 16:38:11 2014 +0300 @@ -52,16 +52,16 @@ float c = dot_product(ray.origin, ray.origin) - 1.0; float d = b * b - 4.0 * a * c; - if(d < 1e-6) return false; + if(d < 1e-5) return false; float sqrt_d = sqrt(d); float t0 = (-b + sqrt_d) / (2.0 * a); float t1 = (-b - sqrt_d) / (2.0 * a); - if(t0 < 1e-6) t0 = t1; - if(t1 < 1e-6) t1 = t0; + if(t0 < 1e-5) t0 = t1; + if(t1 < 1e-5) t1 = t0; float t = t0 < t1 ? t0 : t1; - if(t < 1e-6) return false; + if(t < 1e-5) return false; if(hit) { hit->dist = t; @@ -146,8 +146,8 @@ tmax = tzmax; } - float t = tmin < 1e-4 ? tmax : tmin; - if(t >= 1e-4) { + float t = tmin < 1e-5 ? tmax : tmin; + if(t >= 1e-5) { if(hit) { hit->obj = this; hit->dist = t; diff -r b9294cd6b9dc -r ed18af9da8f7 liberebus/src/rt.cc --- a/liberebus/src/rt.cc Tue Jun 10 16:15:08 2014 +0300 +++ b/liberebus/src/rt.cc Wed Jun 11 16:38:11 2014 +0300 @@ -9,6 +9,11 @@ return Color(1, 0, 0); } + if(iter > erb_getopti(ctx, ERB_OPT_MAX_ITER) || ray.energy < 0.0001) { + //return Color(1, 0, 1); + return Color(0, 0, 0); + } + RayHit hit; if(!(scn->intersect(ray, &hit))) { return scn->get_env_color(ray); @@ -20,7 +25,6 @@ Color shade(struct erebus *ctx, const RayHit &hit, int iter) { assert(hit.obj->get_type() == ObjType::geom); - int max_iter = erb_getopti(ctx, ERB_OPT_MAX_ITER); const Scene *scn = ctx->scn; const GeomObject *obj = (const GeomObject*)hit.obj; const Material *mtl = &obj->mtl; @@ -28,6 +32,8 @@ const Ray &ray = hit.world_ray; //bool entering = true; + Vector3 pos = ray.origin + ray.dir * hit.dist; + Vector3 norm = hit.calc_normal(); if(dot_product(ray.dir, norm) > 0.0) { //entering = false; @@ -39,15 +45,73 @@ Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y); Color specular = mtl->get_attrib_color("specular", texcoords.x, texcoords.y); - Color res = mtl->get_attrib_color("emissive", texcoords.x, texcoords.y) + - color * scn->get_env().ambient; + Color res = color * scn->get_env().ambient; float shininess = mtl->get_attrib_value("shininess"); + res += mtl->get_attrib_color("emissive", texcoords.x, texcoords.y); + + /* + // calculate direct illumination + Vector3 vdir = -ray.dir.normalized(); + std::list lights = scn->gen_light_list(); + auto it = lights.cbegin(); + while(it != lights.cend()) { + const ObjectInstance &inst = *it++; + GeomObject *light = (GeomObject*)inst.obj; + SceneNode *light_node = inst.node; + + if(obj == light) { + // don't try to get illumination from ourselves + continue; + } + + const Matrix4x4 &xform = light_node->get_matrix(); + const Matrix4x4 &inv_xform = light_node->get_inv_matrix(); + Vector3 spt = light->gen_surface_point().transformed(xform); + + Vector3 ldir = spt - pos; + if(dot_product(ldir, norm) < 0.0) { + continue; + } + Ray shadow_ray{pos, ldir}; + + RayHit shadow_hit; + shadow_hit.obj = 0; + if(scn->intersect(shadow_ray, &shadow_hit) && shadow_hit.obj != light && + shadow_hit.dist < 0.99999 && shadow_hit.dist > 1e-5) { + // we're in shadow, skip + continue; + } + + if(!shadow_hit.obj) { + shadow_hit.obj = light; + shadow_hit.dist = 1.0; + shadow_hit.world_ray = shadow_ray; + shadow_hit.local_ray = shadow_ray.transformed(inv_xform); + shadow_hit.node = inst.node; + } + + Vector2 tc = shadow_hit.calc_texcoords(); + Color lcol = light->mtl.get_attrib_color("emissive", tc.x, tc.y); + + ldir.normalize(); + norm.normalize(); + float ndotl = dot_product(ldir, norm); + + Vector3 refl = ldir.reflection(norm); + float vdotr = dot_product(vdir, refl); + + Color direct = ray.energy * lcol * (color * ndotl);// + specular * pow(vdotr, shininess)); + assert(direct.x >= 0.0 && direct.y >= 0.0 && direct.z >= 0.0); + res += direct; + } + */ + Vector3 sample_dir; - float prob = brdf->sample(SurfaceGeometry(norm), -hit.world_ray.dir, &sample_dir); - if(iter < max_iter && randf() <= prob && ray.energy * prob > 0.001) { + float prob = brdf->sample(SurfaceGeometry(norm), -ray.dir, &sample_dir); + if(randf() <= prob) { Ray sample_ray; - sample_ray.origin = ray.origin + ray.dir * hit.dist; + sample_ray.origin = pos; sample_ray.dir = sample_dir; sample_ray.energy = ray.energy * prob; diff -r b9294cd6b9dc -r ed18af9da8f7 liberebus/src/scene.cc --- a/liberebus/src/scene.cc Tue Jun 10 16:15:08 2014 +0300 +++ b/liberebus/src/scene.cc Wed Jun 11 16:38:11 2014 +0300 @@ -111,6 +111,31 @@ return active_cam; } +std::list Scene::gen_light_list() const +{ + std::list list; + + for(auto n : nodes) { + int nobj = n->get_num_objects(); + for(int i=0; iget_object(i); + if(o->get_type() != ObjType::geom) { + continue; + } + GeomObject *go = (GeomObject*)o; + + if(go->mtl.get_attrib_value("emissive") > 0.0) { + ObjectInstance inst; + inst.obj = go; + inst.node = n; + + list.push_back(inst); + } + } + } + return std::move(list); +} + void Scene::update(long msec) { root->update(msec); diff -r b9294cd6b9dc -r ed18af9da8f7 liberebus/src/scene.h --- a/liberebus/src/scene.h Tue Jun 10 16:15:08 2014 +0300 +++ b/liberebus/src/scene.h Wed Jun 11 16:38:11 2014 +0300 @@ -56,6 +56,8 @@ void use_camera(Camera *cam); Camera *get_active_camera() const; + std::list gen_light_list() const; + void update(long msec = 0); bool intersect(const Ray &ray, RayHit *hit) const; diff -r b9294cd6b9dc -r ed18af9da8f7 test/scene --- a/test/scene Tue Jun 10 16:15:08 2014 +0300 +++ b/test/scene Wed Jun 11 16:38:11 2014 +0300 @@ -9,6 +9,6 @@ -brdf mirror -brdf-weight 0.7 box -position 0 3.75 0 -scaling 20 10 20 -diffuse 1.0 1.0 1.0 -brdf lambert -box -position 0 4 0 -scaling 3 0.1 3 -emissive 8 8 8 +box -position 0 4 0 -scaling 3 0.1 3 -emissive 6 6 6 camera -position 0 3 -6 -target 0 0 0