new Raytracer option: oversampling pyrit
authorRadek Brich <radek.brich@devl.cz>
Sun, 09 Dec 2007 13:31:38 +0100
branchpyrit
changeset 32 8af5c17d368b
parent 31 b4e09433934a
child 33 83d0200d4c09
new Raytracer option: oversampling add 9x and 16x oversampling (5x was available through preproc. directive)
TODO
ccdemos/spheres_shadow.cc
include/raytracer.h
src/raytracer.cc
--- a/TODO	Sun Dec 09 10:45:26 2007 +0100
+++ b/TODO	Sun Dec 09 13:31:38 2007 +0100
@@ -12,6 +12,7 @@
  * textures (3D procedural, pixmaps later)
  * update Python binding: Camera, new classes
  * namespace
+ * stochastic oversampling
 
 New Classes?
 ============
--- a/ccdemos/spheres_shadow.cc	Sun Dec 09 10:45:26 2007 +0100
+++ b/ccdemos/spheres_shadow.cc	Sun Dec 09 13:31:38 2007 +0100
@@ -5,6 +5,8 @@
 {
 	Raytracer rt;
 	rt.setThreads(2);
+	rt.setOversample(0);
+	rt.setSubsample(8);
 
 	KdTree top;
 	rt.setTop(&top);
--- a/include/raytracer.h	Sun Dec 09 10:45:26 2007 +0100
+++ b/include/raytracer.h	Sun Dec 09 13:31:38 2007 +0100
@@ -34,12 +34,13 @@
 	Float ao_distance, ao_angle;
 	int num_threads;
 	int subsample;
+	int oversample; // 0 = no, 1 = 5x, 2 = 9x, 3 = 16x
 	int max_depth;
 
 	Vector3 SphereDistribute(int i, int n, Float extent, Vector3 &normal);
 public:
 	Raytracer(): top(NULL), camera(NULL), lights(), bg_colour(0.0, 0.0, 0.0),
-		ao_samples(0), num_threads(2), subsample(8), max_depth(3) {};
+		ao_samples(0), num_threads(2), subsample(8), oversample(0), max_depth(3) {};
 	void render(int w, int h, Float *buffer);
 	Colour raytrace(Ray &ray, int depth, Shape *origin_shape);
 	void addshape(Shape *shape) { top->addShape(shape); };
@@ -47,7 +48,10 @@
 	void setCamera(Camera *cam) { camera = cam; };
 	void setTop(Container *atop) { top = atop; };
 	Container *getTop() { return top; };
+	void setSubsample(int sub) { subsample = sub; };
 	int getSubsample() { return subsample; };
+	void setOversample(int osa) { oversample = osa; };
+	int getOversample() { return oversample; };
 	void setMaxDepth(int newdepth) { max_depth = newdepth; };
 
 	void ambientocclusion(int samples, Float distance, Float angle);
--- a/src/raytracer.cc	Sun Dec 09 10:45:26 2007 +0100
+++ b/src/raytracer.cc	Sun Dec 09 13:31:38 2007 +0100
@@ -214,39 +214,24 @@
 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;
+	const int subsample = d->rt->getSubsample();
+	const Float subsample2 = 1.0/(subsample*subsample);
+	const int oversample = d->rt->getOversample();
+	const int ww = d->w*3;
 	Vector3 dir = d->dfix;
 	for (int x = 0; x < d->w; x += subsample) {
 		// generate a ray from eye passing through this pixel
-#if OVERSAMPLING
-		// 5x oversampling
-		Colour c = Colour();
-
-		for (int i = 0; i < 5; i++)
-		{
-			Float osax[] = {0.0, -0.4, +0.4, +0.4, -0.4};
-			Float osay[] = {0.0, -0.4, -0.4, +0.4, +0.4};
-			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./5);
-#else
-		// no oversampling
-		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-left
+			dir.normalize();
+			Ray ray(d->eye, dir);
+			Colour c1 = d->rt->raytrace(ray, 0, NULL);
 			// top-right
 			Vector3 tmpdir = dir + (subsample-1)*d->dx;
 			tmpdir.normalize();
-			Ray ray(d->eye, tmpdir);
+			ray.dir = tmpdir;
 			Colour c2 = d->rt->raytrace(ray, 0, NULL);
 			// bottom right
 			tmpdir += (subsample-1)*d->dy;
@@ -259,10 +244,10 @@
 			ray.dir = tmpdir;
 			Colour c3 = d->rt->raytrace(ray, 0, NULL);
 			// are the colors similar?
-			Float m = (c-c2).mag2();
+			Float m = (c1-c2).mag2();
 			m = max(m, (c2-c3).mag2());
 			m = max(m, (c3-c4).mag2());
-			m = max(m, (c4-c).mag2());
+			m = max(m, (c4-c1).mag2());
 			if (m < 0.001)
 			{
 				// interpolate
@@ -271,7 +256,7 @@
 				{
 					for (int y = 0; y < subsample; y++)
 					{
-						ic = c*(subsample-x)*(subsample-y)*subsample2
+						ic = c1*(subsample-x)*(subsample-y)*subsample2
 							+ c2*(x)*(subsample-y)*subsample2
 							+ c3*(subsample-x)*(y)*subsample2
 							+ c4*(x)*(y)*subsample2;
@@ -288,9 +273,9 @@
 				// render
 				Vector3 tmpdir = dir;
 				// first column
-				*(d->iter) = c.r;
-				*(d->iter + 1) = c.g;
-				*(d->iter + 2) = c.b;
+				*(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;
@@ -342,9 +327,53 @@
 				d->iter += 3;
 			}
 		}
-#endif
-		if (subsample <= 1)
+		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
+			}
+			// write color to buffer
 			*d->iter++ = c.r;
 			*d->iter++ = c.g;
 			*d->iter++ = c.b;