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