nuclear@8: #include nuclear@6: #include "rt.h" nuclear@8: #include "erebus_impl.h" nuclear@8: nuclear@8: #define MAX_ITER 8 nuclear@6: nuclear@6: Color ray_trace(const Ray &ray, const Scene *scn, int iter) nuclear@6: { nuclear@6: RayHit hit; nuclear@6: if(!(scn->intersect(ray, &hit))) { nuclear@8: return scn->get_env_color(ray); nuclear@6: } nuclear@6: nuclear@8: return shade(hit, scn, iter); nuclear@6: } nuclear@6: nuclear@8: Color shade(const RayHit &hit, const Scene *scn, int iter) nuclear@6: { nuclear@8: assert(hit.obj->get_type() == ObjType::geom); nuclear@8: const GeomObject *obj = (const GeomObject*)hit.obj; nuclear@8: const Material *mtl = &obj->mtl; nuclear@8: const Reflectance *brdf = obj->brdf; nuclear@8: const Ray &ray = hit.world_ray; nuclear@8: nuclear@8: Vector3 norm = obj->calc_normal(hit); nuclear@8: Vector2 texcoords = obj->calc_texcoords(hit); nuclear@8: nuclear@8: Color color = mtl->get_attrib_color("albedo", texcoords.x, texcoords.y); nuclear@8: Color res = mtl->get_attrib_color("emissive") + color * scn->get_env().ambient; nuclear@8: nuclear@8: Vector3 sample_dir; nuclear@8: float prob = brdf->sample(norm, -hit.world_ray.dir, &sample_dir); nuclear@8: if(iter < MAX_ITER && randf() <= prob) { nuclear@8: Ray sample_ray; nuclear@8: sample_ray.origin = ray.origin + ray.dir * hit.dist; nuclear@8: sample_ray.dir = sample_dir; nuclear@8: nuclear@8: res += ray_trace(sample_ray, scn, iter + 1) * color; nuclear@8: } nuclear@8: return res; nuclear@6: }