src/raytracer.cc
branchpyrit
changeset 33 83d0200d4c09
parent 32 8af5c17d368b
child 34 28f6e8b9d5d1
equal deleted inserted replaced
32:8af5c17d368b 33:83d0200d4c09
   206 			Float ao_intensity = miss / ao_samples;
   206 			Float ao_intensity = miss / ao_samples;
   207 			col = col * ao_intensity;
   207 			col = col * ao_intensity;
   208 		}
   208 		}
   209 
   209 
   210 		return col;
   210 		return col;
       
   211 	}
       
   212 }
       
   213 
       
   214 static inline void samplepixel(Colour &c, Vector3 &dir, RenderrowData* d, const int &oversample)
       
   215 {
       
   216 	if (oversample <= 0)
       
   217 	{
       
   218 		// no oversampling
       
   219 		dir.normalize();
       
   220 		Ray ray(d->eye, dir);
       
   221 		c = d->rt->raytrace(ray, 0, NULL);
       
   222 	}
       
   223 	else
       
   224 	if (oversample <= 3)
       
   225 	{
       
   226 		// grid oversampling
       
   227 		c = Colour(0,0,0);
       
   228 		static const int gridsamples[] = {5,9,16};
       
   229 		static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
       
   230 		static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4};
       
   231 		static const Float osa9x[] = {-0.34,  0.00, +0.34,
       
   232 			-0.34,  0.00, +0.34, -0.34,  0.00, +0.34};
       
   233 		static const Float osa9y[] = {-0.34, -0.34, -0.34,
       
   234 				0.00,  0.00,  0.00, +0.34, +0.34, +0.34};
       
   235 		static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375,
       
   236 			-0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375,
       
   237 			-0.375, -0.125, +0.125, +0.375};
       
   238 		static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375,
       
   239 			-0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125,
       
   240 			+0.375, +0.375, +0.375, +0.375};
       
   241 		static const Float *osaSx[] = {osa5x, osa9x, osa16x};
       
   242 		static const Float *osaSy[] = {osa5y, osa9y, osa16y};
       
   243 		const int samples = gridsamples[oversample-1];
       
   244 		const Float *osax = osaSx[oversample-1];
       
   245 		const Float *osay = osaSy[oversample-1];
       
   246 		for (int i = 0; i < samples; i++)
       
   247 		{
       
   248 			Vector3 tmpdir = dir + osax[i]*d->dx + osay[i]*d->dy;
       
   249 			tmpdir.normalize();
       
   250 			Ray ray(d->eye, tmpdir);
       
   251 			c += d->rt->raytrace(ray, 0, NULL);
       
   252 		}
       
   253 		c = c * (1.0/samples);
       
   254 	}
       
   255 	else
       
   256 	{
       
   257 		// stochastic oversampling
       
   258 		// ...todo
   211 	}
   259 	}
   212 }
   260 }
   213 
   261 
   214 static void *renderrow(void *data)
   262 static void *renderrow(void *data)
   215 {
   263 {
   268 				}
   316 				}
   269 				d->iter = i;
   317 				d->iter = i;
   270 			}
   318 			}
   271 			else
   319 			else
   272 			{
   320 			{
   273 				// render
   321 				// render all pixels
   274 				Vector3 tmpdir = dir;
   322 				Vector3 tmpdir = dir;
   275 				// first column
   323 
   276 				*(d->iter) = c1.r;
   324 				if (oversample)
   277 				*(d->iter + 1) = c1.g;
   325 				{
   278 				*(d->iter + 2) = c1.b;
   326 					for (int x = 0; x < subsample; x++)
   279 				for (int y = 1; y < subsample-1; y++)
   327 					{
   280 				{
   328 						for (int y = 0; y < subsample; y++)
   281 					Vector3 tmp2dir = tmpdir + y*d->dy;
   329 						{
   282 					tmp2dir.normalize();
   330 							Vector3 tmp2dir = tmpdir + y*d->dy;
   283 					ray.dir = tmp2dir;
   331 							samplepixel(ic, tmp2dir, d, oversample);
   284 					ic = d->rt->raytrace(ray, 0, NULL);
   332 							*(d->iter + ww*y) = ic.r;
   285 					*(d->iter + ww*y) = ic.r;
   333 							*(d->iter + ww*y + 1) = ic.g;
   286 					*(d->iter + ww*y + 1) = ic.g;
   334 							*(d->iter + ww*y + 2) = ic.b;
   287 					*(d->iter + ww*y + 2) = ic.b;
   335 						}
   288 				}
   336 						d->iter += 3;
   289 				*(d->iter + ww*(subsample-1)) = c3.r;
   337 						tmpdir += d->dx;
   290 				*(d->iter + ww*(subsample-1) + 1) = c3.g;
   338 					}
   291 				*(d->iter + ww*(subsample-1) + 2) = c3.b;
   339 				}
   292 				d->iter += 3;
   340 				else
   293 				tmpdir += d->dx;
   341 				{
   294 				// middle
   342 					/* this is so complex because it tries to reuse
   295 				for (int x = 1; x < subsample-1; x++)
   343 					   already computed corner pixels
   296 				{
   344 					   though, above code will also work for non-oversampling... */
   297 					for (int y = 0; y < subsample; y++)
   345 					// first column
       
   346 					*(d->iter) = c1.r;
       
   347 					*(d->iter + 1) = c1.g;
       
   348 					*(d->iter + 2) = c1.b;
       
   349 					for (int y = 1; y < subsample-1; y++)
   298 					{
   350 					{
   299 						Vector3 tmp2dir = tmpdir + y*d->dy;
   351 						Vector3 tmp2dir = tmpdir + y*d->dy;
   300 						tmp2dir.normalize();
   352 						tmp2dir.normalize();
   301 						ray.dir = tmp2dir;
   353 						ray.dir = tmp2dir;
   302 						ic = d->rt->raytrace(ray, 0, NULL);
   354 						ic = d->rt->raytrace(ray, 0, NULL);
   303 						*(d->iter + ww*y) = ic.r;
   355 						*(d->iter + ww*y) = ic.r;
   304 						*(d->iter + ww*y + 1) = ic.g;
   356 						*(d->iter + ww*y + 1) = ic.g;
   305 						*(d->iter + ww*y + 2) = ic.b;
   357 						*(d->iter + ww*y + 2) = ic.b;
   306 					}
   358 					}
       
   359 					*(d->iter + ww*(subsample-1)) = c3.r;
       
   360 					*(d->iter + ww*(subsample-1) + 1) = c3.g;
       
   361 					*(d->iter + ww*(subsample-1) + 2) = c3.b;
   307 					d->iter += 3;
   362 					d->iter += 3;
   308 					tmpdir += d->dx;
   363 					tmpdir += d->dx;
   309 				}
   364 					// middle
   310 				// last column
   365 					for (int x = 1; x < subsample-1; x++)
   311 				*(d->iter) = c2.r;
   366 					{
   312 				*(d->iter + 1) = c2.g;
   367 						for (int y = 0; y < subsample; y++)
   313 				*(d->iter + 2) = c2.b;
   368 						{
   314 				for (int y = 1; y < subsample-1; y++)
   369 							Vector3 tmp2dir = tmpdir + y*d->dy;
   315 				{
   370 							tmp2dir.normalize();
   316 					Vector3 tmp2dir = tmpdir + y*d->dy;
   371 							ray.dir = tmp2dir;
   317 					tmp2dir.normalize();
   372 							ic = d->rt->raytrace(ray, 0, NULL);
   318 					ray.dir = tmp2dir;
   373 							*(d->iter + ww*y) = ic.r;
   319 					ic = d->rt->raytrace(ray, 0, NULL);
   374 							*(d->iter + ww*y + 1) = ic.g;
   320 					*(d->iter + ww*y) = ic.r;
   375 							*(d->iter + ww*y + 2) = ic.b;
   321 					*(d->iter + ww*y + 1) = ic.g;
   376 						}
   322 					*(d->iter + ww*y + 2) = ic.b;
   377 						d->iter += 3;
   323 				}
   378 						tmpdir += d->dx;
   324 				*(d->iter + ww*(subsample-1)) = c4.r;
   379 					}
   325 				*(d->iter + ww*(subsample-1) + 1) = c4.g;
   380 					// last column
   326 				*(d->iter + ww*(subsample-1) + 2) = c4.b;
   381 					*(d->iter) = c2.r;
   327 				d->iter += 3;
   382 					*(d->iter + 1) = c2.g;
       
   383 					*(d->iter + 2) = c2.b;
       
   384 					for (int y = 1; y < subsample-1; y++)
       
   385 					{
       
   386 						Vector3 tmp2dir = tmpdir + y*d->dy;
       
   387 						tmp2dir.normalize();
       
   388 						ray.dir = tmp2dir;
       
   389 						ic = d->rt->raytrace(ray, 0, NULL);
       
   390 						*(d->iter + ww*y) = ic.r;
       
   391 						*(d->iter + ww*y + 1) = ic.g;
       
   392 						*(d->iter + ww*y + 2) = ic.b;
       
   393 					}
       
   394 					*(d->iter + ww*(subsample-1)) = c4.r;
       
   395 					*(d->iter + ww*(subsample-1) + 1) = c4.g;
       
   396 					*(d->iter + ww*(subsample-1) + 2) = c4.b;
       
   397 					d->iter += 3;
       
   398 				}
   328 			}
   399 			}
   329 		}
   400 		}
   330 		else // subsample <= 1
   401 		else // subsample <= 1
   331 		{
   402 		{
   332 			Colour c;
   403 			Colour c;
   333 			if (oversample <= 0)
   404 			samplepixel(c, dir, d, oversample);
   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
   405 			// write color to buffer
   377 			*d->iter++ = c.r;
   406 			*d->iter++ = c.r;
   378 			*d->iter++ = c.g;
   407 			*d->iter++ = c.g;
   379 			*d->iter++ = c.b;
   408 			*d->iter++ = c.b;
   380 		}
   409 		}