make over-sampling work together with sub-sampling pyrit
authorRadek Brich <radek.brich@devl.cz>
Sun, 09 Dec 2007 15:01:51 +0100
branchpyrit
changeset 33 83d0200d4c09
parent 32 8af5c17d368b
child 34 28f6e8b9d5d1
make over-sampling work together with sub-sampling
src/raytracer.cc
--- a/src/raytracer.cc	Sun Dec 09 13:31:38 2007 +0100
+++ b/src/raytracer.cc	Sun Dec 09 15:01:51 2007 +0100
@@ -211,6 +211,54 @@
 	}
 }
 
+static inline void samplepixel(Colour &c, Vector3 &dir, RenderrowData* d, const int &oversample)
+{
+	if (oversample <= 0)
+	{
+		// no oversampling
+		dir.normalize();
+		Ray ray(d->eye, dir);
+		c = d->rt->raytrace(ray, 0, NULL);
+	}
+	else
+	if (oversample <= 3)
+	{
+		// grid oversampling
+		c = Colour(0,0,0);
+		static const int gridsamples[] = {5,9,16};
+		static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
+		static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4};
+		static const Float osa9x[] = {-0.34,  0.00, +0.34,
+			-0.34,  0.00, +0.34, -0.34,  0.00, +0.34};
+		static const Float osa9y[] = {-0.34, -0.34, -0.34,
+				0.00,  0.00,  0.00, +0.34, +0.34, +0.34};
+		static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375,
+			-0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375,
+			-0.375, -0.125, +0.125, +0.375};
+		static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375,
+			-0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125,
+			+0.375, +0.375, +0.375, +0.375};
+		static const Float *osaSx[] = {osa5x, osa9x, osa16x};
+		static const Float *osaSy[] = {osa5y, osa9y, osa16y};
+		const int samples = gridsamples[oversample-1];
+		const Float *osax = osaSx[oversample-1];
+		const Float *osay = osaSy[oversample-1];
+		for (int i = 0; i < samples; i++)
+		{
+			Vector3 tmpdir = dir + osax[i]*d->dx + osay[i]*d->dy;
+			tmpdir.normalize();
+			Ray ray(d->eye, tmpdir);
+			c += d->rt->raytrace(ray, 0, NULL);
+		}
+		c = c * (1.0/samples);
+	}
+	else
+	{
+		// stochastic oversampling
+		// ...todo
+	}
+}
+
 static void *renderrow(void *data)
 {
 	RenderrowData *d = (RenderrowData*) data;
@@ -270,31 +318,35 @@
 			}
 			else
 			{
-				// render
+				// render all pixels
 				Vector3 tmpdir = dir;
-				// first column
-				*(d->iter) = c1.r;
-				*(d->iter + 1) = c1.g;
-				*(d->iter + 2) = c1.b;
-				for (int y = 1; y < subsample-1; y++)
+
+				if (oversample)
 				{
-					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;
+					for (int x = 0; x < subsample; x++)
+					{
+						for (int y = 0; y < subsample; y++)
+						{
+							Vector3 tmp2dir = tmpdir + y*d->dy;
+							samplepixel(ic, tmp2dir, d, oversample);
+							*(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;
+					}
 				}
-				*(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++)
+				else
 				{
-					for (int y = 0; y < subsample; y++)
+					/* this is so complex because it tries to reuse
+					   already computed corner pixels
+					   though, above code will also work for non-oversampling... */
+					// first column
+					*(d->iter) = c1.r;
+					*(d->iter + 1) = c1.g;
+					*(d->iter + 2) = c1.b;
+					for (int y = 1; y < subsample-1; y++)
 					{
 						Vector3 tmp2dir = tmpdir + y*d->dy;
 						tmp2dir.normalize();
@@ -304,75 +356,52 @@
 						*(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;
 				}
-				// 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;
 			}
 		}
 		else // subsample <= 1
 		{
 			Colour c;
-			if (oversample <= 0)
-			{
-				// no oversampling
-				dir.normalize();
-				Ray ray(d->eye, dir);
-				c = d->rt->raytrace(ray, 0, NULL);
-			}
-			else
-			if (oversample <= 3)
-			{
-				// grid oversampling
-				static const int gridsamples[] = {5,9,16};
-				static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
-				static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4};
-				static const Float osa9x[] = {-0.34,  0.00, +0.34,
-					-0.34,  0.00, +0.34, -0.34,  0.00, +0.34};
-				static const Float osa9y[] = {-0.34, -0.34, -0.34,
-					 0.00,  0.00,  0.00, +0.34, +0.34, +0.34};
-				static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375,
-					-0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375,
-					-0.375, -0.125, +0.125, +0.375};
-				static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375,
-					-0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125,
-					+0.375, +0.375, +0.375, +0.375};
-				static const Float *osaSx[] = {osa5x, osa9x, osa16x};
-				static const Float *osaSy[] = {osa5y, osa9y, osa16y};
-				const int samples = gridsamples[oversample-1];
-				const Float *osax = osaSx[oversample-1];
-				const Float *osay = osaSy[oversample-1];
-				for (int i = 0; i < samples; i++)
-				{
-					Vector3 tmpdir = dir + osax[i]*d->dx + osay[i]*d->dy;
-					tmpdir.normalize();
-					Ray ray(d->eye, tmpdir);
-					c += d->rt->raytrace(ray, 0, NULL);
-				}
-				c = c * (1.0/samples);
-			}
-			else
-			{
-				// stochastic oversampling
-				// ...todo
-			}
+			samplepixel(c, dir, d, oversample);
 			// write color to buffer
 			*d->iter++ = c.r;
 			*d->iter++ = c.g;