diff -r f22952603f29 -r 79b516a3803d src/raytracer.cc --- 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");