--- 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;