erebus

annotate liberebus/src/rt.cc @ 29:fb20e3855740

write the rendered image when pressing '`' and on exit.
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 06 Jun 2014 15:08:09 +0300
parents 4a0a288ffb27
children 53a98c148bf8
rev   line source
nuclear@8 1 #include <assert.h>
nuclear@6 2 #include "rt.h"
nuclear@8 3 #include "erebus_impl.h"
nuclear@8 4
nuclear@28 5 #define MAX_ITER 6
nuclear@6 6
nuclear@17 7 Color ray_trace(struct erebus *ctx, const Ray &ray, int iter)
nuclear@6 8 {
nuclear@17 9 const Scene *scn = ctx->scn;
nuclear@17 10 if(!scn) {
nuclear@17 11 return Color(1, 0, 0);
nuclear@17 12 }
nuclear@17 13
nuclear@6 14 RayHit hit;
nuclear@6 15 if(!(scn->intersect(ray, &hit))) {
nuclear@8 16 return scn->get_env_color(ray);
nuclear@6 17 }
nuclear@6 18
nuclear@17 19 return shade(ctx, hit, iter);
nuclear@6 20 }
nuclear@6 21
nuclear@17 22 Color shade(struct erebus *ctx, const RayHit &hit, int iter)
nuclear@6 23 {
nuclear@8 24 assert(hit.obj->get_type() == ObjType::geom);
nuclear@17 25 int max_iter = erb_getopti(ctx, ERB_OPT_MAX_ITER);
nuclear@17 26 const Scene *scn = ctx->scn;
nuclear@8 27 const GeomObject *obj = (const GeomObject*)hit.obj;
nuclear@8 28 const Material *mtl = &obj->mtl;
nuclear@8 29 const Reflectance *brdf = obj->brdf;
nuclear@8 30 const Ray &ray = hit.world_ray;
nuclear@26 31 //bool entering = true;
nuclear@8 32
nuclear@17 33 Vector3 norm = hit.calc_normal();
nuclear@23 34 if(dot_product(ray.dir, norm) > 0.0) {
nuclear@26 35 //entering = false;
nuclear@23 36 norm = -norm;
nuclear@23 37 }
nuclear@23 38
nuclear@18 39 //return norm * 0.5 + Vector3(0.5, 0.5, 0.5);
nuclear@17 40 Vector2 texcoords = hit.calc_texcoords();
nuclear@8 41
nuclear@17 42 Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y);
nuclear@28 43 Color specular = mtl->get_attrib_color("specular", texcoords.x, texcoords.y);
nuclear@28 44 Color res = mtl->get_attrib_color("emissive", texcoords.x, texcoords.y) +
nuclear@28 45 color * scn->get_env().ambient;
nuclear@28 46 float shininess = mtl->get_attrib_value("shininess");
nuclear@8 47
nuclear@8 48 Vector3 sample_dir;
nuclear@8 49 float prob = brdf->sample(norm, -hit.world_ray.dir, &sample_dir);
nuclear@28 50 if(iter < max_iter && randf() <= prob && ray.energy * prob > 0.001) {
nuclear@8 51 Ray sample_ray;
nuclear@8 52 sample_ray.origin = ray.origin + ray.dir * hit.dist;
nuclear@8 53 sample_ray.dir = sample_dir;
nuclear@28 54 sample_ray.energy = ray.energy * prob;
nuclear@8 55
nuclear@17 56 res += ray_trace(ctx, sample_ray, iter + 1) * color;
nuclear@8 57 }
nuclear@29 58
nuclear@29 59 res.w = 1.0;
nuclear@8 60 return res;
nuclear@6 61 }