src/raytracer.cc
branchpyrit
changeset 32 8af5c17d368b
parent 31 b4e09433934a
child 33 83d0200d4c09
equal deleted inserted replaced
31:b4e09433934a 32:8af5c17d368b
   212 }
   212 }
   213 
   213 
   214 static void *renderrow(void *data)
   214 static void *renderrow(void *data)
   215 {
   215 {
   216 	RenderrowData *d = (RenderrowData*) data;
   216 	RenderrowData *d = (RenderrowData*) data;
   217 	int subsample = d->rt->getSubsample();
   217 	const int subsample = d->rt->getSubsample();
   218 	Float subsample2 = 1.0/(subsample*subsample);
   218 	const Float subsample2 = 1.0/(subsample*subsample);
   219 	int ww = d->w*3;
   219 	const int oversample = d->rt->getOversample();
       
   220 	const int ww = d->w*3;
   220 	Vector3 dir = d->dfix;
   221 	Vector3 dir = d->dfix;
   221 	for (int x = 0; x < d->w; x += subsample) {
   222 	for (int x = 0; x < d->w; x += subsample) {
   222 		// generate a ray from eye passing through this pixel
   223 		// generate a ray from eye passing through this pixel
   223 #if OVERSAMPLING
       
   224 		// 5x oversampling
       
   225 		Colour c = Colour();
       
   226 
       
   227 		for (int i = 0; i < 5; i++)
       
   228 		{
       
   229 			Float osax[] = {0.0, -0.4, +0.4, +0.4, -0.4};
       
   230 			Float osay[] = {0.0, -0.4, -0.4, +0.4, +0.4};
       
   231 			Vector3 tmpdir = dir + osax[i]*d->dx + osay[i]*d->dy;
       
   232 			tmpdir.normalize();
       
   233 			Ray ray(d->eye, tmpdir);
       
   234 			c += d->rt->raytrace(ray, 0, NULL);
       
   235 		}
       
   236 		c = c * (1./5);
       
   237 #else
       
   238 		// no oversampling
       
   239 		dir.normalize();
       
   240 		Ray ray(d->eye, dir);
       
   241 		Colour c = d->rt->raytrace(ray, 0, NULL);
       
   242 		if (subsample > 1)
   224 		if (subsample > 1)
   243 		{
   225 		{
   244 			Colour ic;
   226 			Colour ic;
   245 			// top-left is 'c'
   227 			// top-left
       
   228 			dir.normalize();
       
   229 			Ray ray(d->eye, dir);
       
   230 			Colour c1 = d->rt->raytrace(ray, 0, NULL);
   246 			// top-right
   231 			// top-right
   247 			Vector3 tmpdir = dir + (subsample-1)*d->dx;
   232 			Vector3 tmpdir = dir + (subsample-1)*d->dx;
   248 			tmpdir.normalize();
   233 			tmpdir.normalize();
   249 			Ray ray(d->eye, tmpdir);
   234 			ray.dir = tmpdir;
   250 			Colour c2 = d->rt->raytrace(ray, 0, NULL);
   235 			Colour c2 = d->rt->raytrace(ray, 0, NULL);
   251 			// bottom right
   236 			// bottom right
   252 			tmpdir += (subsample-1)*d->dy;
   237 			tmpdir += (subsample-1)*d->dy;
   253 			tmpdir.normalize();
   238 			tmpdir.normalize();
   254 			ray.dir = tmpdir;
   239 			ray.dir = tmpdir;
   257 			tmpdir = dir + (subsample-1)*d->dy;
   242 			tmpdir = dir + (subsample-1)*d->dy;
   258 			tmpdir.normalize();
   243 			tmpdir.normalize();
   259 			ray.dir = tmpdir;
   244 			ray.dir = tmpdir;
   260 			Colour c3 = d->rt->raytrace(ray, 0, NULL);
   245 			Colour c3 = d->rt->raytrace(ray, 0, NULL);
   261 			// are the colors similar?
   246 			// are the colors similar?
   262 			Float m = (c-c2).mag2();
   247 			Float m = (c1-c2).mag2();
   263 			m = max(m, (c2-c3).mag2());
   248 			m = max(m, (c2-c3).mag2());
   264 			m = max(m, (c3-c4).mag2());
   249 			m = max(m, (c3-c4).mag2());
   265 			m = max(m, (c4-c).mag2());
   250 			m = max(m, (c4-c1).mag2());
   266 			if (m < 0.001)
   251 			if (m < 0.001)
   267 			{
   252 			{
   268 				// interpolate
   253 				// interpolate
   269 				Float *i = d->iter;
   254 				Float *i = d->iter;
   270 				for (int x = 0; x < subsample; x++)
   255 				for (int x = 0; x < subsample; x++)
   271 				{
   256 				{
   272 					for (int y = 0; y < subsample; y++)
   257 					for (int y = 0; y < subsample; y++)
   273 					{
   258 					{
   274 						ic = c*(subsample-x)*(subsample-y)*subsample2
   259 						ic = c1*(subsample-x)*(subsample-y)*subsample2
   275 							+ c2*(x)*(subsample-y)*subsample2
   260 							+ c2*(x)*(subsample-y)*subsample2
   276 							+ c3*(subsample-x)*(y)*subsample2
   261 							+ c3*(subsample-x)*(y)*subsample2
   277 							+ c4*(x)*(y)*subsample2;
   262 							+ c4*(x)*(y)*subsample2;
   278 						*(i + ww*y) = ic.r;
   263 						*(i + ww*y) = ic.r;
   279 						*(i + ww*y + 1) = ic.g;
   264 						*(i + ww*y + 1) = ic.g;
   286 			else
   271 			else
   287 			{
   272 			{
   288 				// render
   273 				// render
   289 				Vector3 tmpdir = dir;
   274 				Vector3 tmpdir = dir;
   290 				// first column
   275 				// first column
   291 				*(d->iter) = c.r;
   276 				*(d->iter) = c1.r;
   292 				*(d->iter + 1) = c.g;
   277 				*(d->iter + 1) = c1.g;
   293 				*(d->iter + 2) = c.b;
   278 				*(d->iter + 2) = c1.b;
   294 				for (int y = 1; y < subsample-1; y++)
   279 				for (int y = 1; y < subsample-1; y++)
   295 				{
   280 				{
   296 					Vector3 tmp2dir = tmpdir + y*d->dy;
   281 					Vector3 tmp2dir = tmpdir + y*d->dy;
   297 					tmp2dir.normalize();
   282 					tmp2dir.normalize();
   298 					ray.dir = tmp2dir;
   283 					ray.dir = tmp2dir;
   340 				*(d->iter + ww*(subsample-1) + 1) = c4.g;
   325 				*(d->iter + ww*(subsample-1) + 1) = c4.g;
   341 				*(d->iter + ww*(subsample-1) + 2) = c4.b;
   326 				*(d->iter + ww*(subsample-1) + 2) = c4.b;
   342 				d->iter += 3;
   327 				d->iter += 3;
   343 			}
   328 			}
   344 		}
   329 		}
   345 #endif
   330 		else // subsample <= 1
   346 		if (subsample <= 1)
       
   347 		{
   331 		{
       
   332 			Colour c;
       
   333 			if (oversample <= 0)
       
   334 			{
       
   335 				// no oversampling
       
   336 				dir.normalize();
       
   337 				Ray ray(d->eye, dir);
       
   338 				c = d->rt->raytrace(ray, 0, NULL);
       
   339 			}
       
   340 			else
       
   341 			if (oversample <= 3)
       
   342 			{
       
   343 				// grid oversampling
       
   344 				static const int gridsamples[] = {5,9,16};
       
   345 				static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
       
   346 				static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4};
       
   347 				static const Float osa9x[] = {-0.34,  0.00, +0.34,
       
   348 					-0.34,  0.00, +0.34, -0.34,  0.00, +0.34};
       
   349 				static const Float osa9y[] = {-0.34, -0.34, -0.34,
       
   350 					 0.00,  0.00,  0.00, +0.34, +0.34, +0.34};
       
   351 				static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375,
       
   352 					-0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375,
       
   353 					-0.375, -0.125, +0.125, +0.375};
       
   354 				static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375,
       
   355 					-0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125,
       
   356 					+0.375, +0.375, +0.375, +0.375};
       
   357 				static const Float *osaSx[] = {osa5x, osa9x, osa16x};
       
   358 				static const Float *osaSy[] = {osa5y, osa9y, osa16y};
       
   359 				const int samples = gridsamples[oversample-1];
       
   360 				const Float *osax = osaSx[oversample-1];
       
   361 				const Float *osay = osaSy[oversample-1];
       
   362 				for (int i = 0; i < samples; i++)
       
   363 				{
       
   364 					Vector3 tmpdir = dir + osax[i]*d->dx + osay[i]*d->dy;
       
   365 					tmpdir.normalize();
       
   366 					Ray ray(d->eye, tmpdir);
       
   367 					c += d->rt->raytrace(ray, 0, NULL);
       
   368 				}
       
   369 				c = c * (1.0/samples);
       
   370 			}
       
   371 			else
       
   372 			{
       
   373 				// stochastic oversampling
       
   374 				// ...todo
       
   375 			}
       
   376 			// write color to buffer
   348 			*d->iter++ = c.r;
   377 			*d->iter++ = c.r;
   349 			*d->iter++ = c.g;
   378 			*d->iter++ = c.g;
   350 			*d->iter++ = c.b;
   379 			*d->iter++ = c.b;
   351 		}
   380 		}
   352 		dir += d->dx*subsample;
   381 		dir += d->dx*subsample;