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