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