diff -r 8af5c17d368b -r 83d0200d4c09 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;