src/raytracer.cc
branchpyrit
changeset 21 79b516a3803d
parent 20 f22952603f29
child 22 76b7bd51d64a
--- a/src/raytracer.cc	Thu Nov 29 18:30:16 2007 +0100
+++ b/src/raytracer.cc	Fri Nov 30 00:44:51 2007 +0100
@@ -109,7 +109,7 @@
 			float L_dot_N = dot(L, normal);
 			if (L_dot_N > 0) {
 				// test if this light is occluded (sharp shadows)
-				if ((*light)->shadows) {
+				if ((*light)->cast_shadows) {
 					Ray shadow_ray = Ray(P, L);
 					float dist = FLT_MAX;
 					if (top->nearest_intersection(nearest_shape, shadow_ray, dist))
@@ -124,9 +124,8 @@
 		}
 
 		// reflection
-		int trace_max_depth = 4;
 		Vector3 newdir = ray.dir - 2.0 * dot(ray.dir, normal) * normal;
-		if (depth < trace_max_depth && nearest_shape->material->reflection > 0.01) {
+		if (depth < max_depth && nearest_shape->material->reflection > 0.01) {
 			Ray newray = Ray(P, newdir);
 			Colour refl_col = raytrace(newray, depth + 1, nearest_shape);
 			acc += nearest_shape->material->reflection * refl_col;
@@ -160,8 +159,11 @@
 static void *renderrow(void *data)
 {
 	RenderrowData *d = (RenderrowData*) data;
+	int subsample = d->rt->getSubsample();
+	float subsample2 = 1.0/(subsample*subsample);
+	int ww = d->w*3;
 	Vector3 dir = d->dfix;
-	for (int x = 0; x < d->w; x++) {
+	for (int x = 0; x < d->w; x += subsample) {
 		// generate a ray from eye passing through this pixel
 #if OVERSAMPLING
 		// 5x oversampling
@@ -182,11 +184,117 @@
 		dir.normalize();
 		Ray ray(d->eye, dir);
 		Colour c = d->rt->raytrace(ray, 0, NULL);
+		if (subsample > 1)
+		{
+			Colour ic;
+			// top-left is 'c'
+			// top-right
+			Vector3 tmpdir = dir + (subsample-1)*d->dx;
+			tmpdir.normalize();
+			Ray ray(d->eye, tmpdir);
+			Colour c2 = d->rt->raytrace(ray, 0, NULL);
+			// bottom right
+			tmpdir += (subsample-1)*d->dy;
+			tmpdir.normalize();
+			ray.dir = tmpdir;
+			Colour c4 = d->rt->raytrace(ray, 0, NULL);
+			// bottom left
+			tmpdir = dir + (subsample-1)*d->dy;
+			tmpdir.normalize();
+			ray.dir = tmpdir;
+			Colour c3 = d->rt->raytrace(ray, 0, NULL);
+			// are the colors similar?
+			float m = (c-c2).mag2();
+			m = max(m, (c2-c3).mag2());
+			m = max(m, (c3-c4).mag2());
+			m = max(m, (c4-c).mag2());
+			if (m < 0.001)
+			{
+				// interpolate
+				float *i = d->iter;
+				for (int x = 0; x < subsample; x++)
+				{
+					for (int y = 0; y < subsample; y++)
+					{
+						ic = c*(subsample-x)*(subsample-y)*subsample2
+							+ c2*(x)*(subsample-y)*subsample2
+							+ c3*(subsample-x)*(y)*subsample2
+							+ c4*(x)*(y)*subsample2;
+						*(i + ww*y) = ic.r;
+						*(i + ww*y + 1) = ic.g;
+						*(i + ww*y + 2) = ic.b;
+					}
+					i += 3;
+				}
+				d->iter = i;
+			}
+			else
+			{
+				// render
+				Vector3 tmpdir = dir;
+				// first column
+				*(d->iter) = c.r;
+				*(d->iter + 1) = c.g;
+				*(d->iter + 2) = c.b;
+				for (int y = 1; y < subsample-1; y++)
+				{
+					Vector3 tmp2dir = tmpdir + y*d->dy;
+					tmp2dir.normalize();
+					ray.dir = tmp2dir;
+					ic = d->rt->raytrace(ray, 0, NULL);
+					*(d->iter + ww*y) = ic.r;
+					*(d->iter + ww*y + 1) = ic.g;
+					*(d->iter + ww*y + 2) = ic.b;
+				}
+				*(d->iter + ww*(subsample-1)) = c3.r;
+				*(d->iter + ww*(subsample-1) + 1) = c3.g;
+				*(d->iter + ww*(subsample-1) + 2) = c3.b;
+				d->iter += 3;
+				tmpdir += d->dx;
+				// middle
+				for (int x = 1; x < subsample-1; x++)
+				{
+					for (int y = 0; y < subsample; y++)
+					{
+						Vector3 tmp2dir = tmpdir + y*d->dy;
+						tmp2dir.normalize();
+						ray.dir = tmp2dir;
+						ic = d->rt->raytrace(ray, 0, NULL);
+						*(d->iter + ww*y) = ic.r;
+						*(d->iter + ww*y + 1) = ic.g;
+						*(d->iter + ww*y + 2) = ic.b;
+					}
+					d->iter += 3;
+					tmpdir += d->dx;
+				}
+				// last column
+				*(d->iter) = c2.r;
+				*(d->iter + 1) = c2.g;
+				*(d->iter + 2) = c2.b;
+				for (int y = 1; y < subsample-1; y++)
+				{
+					Vector3 tmp2dir = tmpdir + y*d->dy;
+					tmp2dir.normalize();
+					ray.dir = tmp2dir;
+					ic = d->rt->raytrace(ray, 0, NULL);
+					*(d->iter + ww*y) = ic.r;
+					*(d->iter + ww*y + 1) = ic.g;
+					*(d->iter + ww*y + 2) = ic.b;
+				}
+				*(d->iter + ww*(subsample-1)) = c4.r;
+				*(d->iter + ww*(subsample-1) + 1) = c4.g;
+				*(d->iter + ww*(subsample-1) + 2) = c4.b;
+				d->iter += 3;
+			}
+		}
 #endif
-		*(d->iter++) = c.r;
-		*d->iter++ = c.g;
-		*d->iter++ = c.b;
-		dir += d->dx;
+		if (subsample <= 1)
+		{
+			*d->iter++ = c.r;
+			*d->iter++ = c.g;
+			*d->iter++ = c.b;
+		}
+		dir += d->dx*subsample;
 	}
 #ifdef PTHREADS
 	pthread_exit((void *)d);
@@ -217,7 +325,7 @@
 
 	/* for each pixel... */
 	infomsg("* rendering row   0 (  0%% done)");
-	for (int y = 0; y < h; y++)
+	for (int y = 0; y < h; y += subsample)
 	{
 		d = (RenderrowData*) malloc(sizeof(RenderrowData));
 		d->rt = this;
@@ -225,9 +333,7 @@
 		d->eye = camera->eye;
 		d->dfix = dfix;
 		d->dx = dx;
-#if OVERSAMPLING
 		d->dy = dy;
-#endif
 		d->iter = buffer + y*3*w;
 #ifdef PTHREADS
 		/* create new thread and increase 't' */
@@ -248,7 +354,7 @@
 		renderrow((void *)d);
 		free(d);
 #endif
-		dfix += dy;
+		dfix += dy*subsample;
 		infomsg("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1));
 	}
 	infomsg("\n");