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 } |