Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Ebb <matt@mke3.net>2007-10-24 16:42:08 +0400
committerMatt Ebb <matt@mke3.net>2007-10-24 16:42:08 +0400
commita9110ee0333b5dfc8af42919e53c7cd35e1f6cb1 (patch)
tree59ec2efcd073558e259caabc24ad40903fdd7120 /source/blender/render
parent14bbff61fecf95c0cc9dc20a480985d599159470 (diff)
* Adaptive QMC AO feature - "Adapt from speed vectors"
This is a new feature that can make using AO a lot more attractive when rendering animations with vector blur. It uses the speed vector info calculated in the 'Vec' speed vector pass, in order to reduce AO samples where pixels are moving more quickly. There's not much point calculating all those AO samples when the result is going to be smeared anyway, so you can save a bit of render time by doing a more noisy render in those areas. You can use this with a new slider in the Adaptive QMC settings 'Adapt Vec'. The higher the value, the more aggressively it will reduce samples. 0.0 means no reduction, and 1.0 reduces one sample per pixel of average displacement for that pixel. 0.25 or so generally gives decent results, but it depends on how fast things are moving. Here's a demo (compare the final blurred result, and render times): http://mke3.net/blender/devel/raytracing/adapt_speed_off2.jpg http://mke3.net/blender/devel/raytracing/adapt_speed_on2.jpg And a less contrived example, a short clip from macouno's 'petunia' bconf animation: http://mke3.net/blender/devel/raytracing/petunia-adaptvec-noblur-h264.mov http://mke3.net/blender/devel/raytracing/petunia-adaptvec-blur-h264.mov
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/source/rayshade.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 560d2151e42..3a859b083ed 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -806,6 +806,23 @@ static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num)
vec[2] = 1.f - s[1]*s[1];
}
+/* cosine weighted hemisphere sampling */
+static void QMC_sampleHemiCosine(float *vec, QMCSampler *qsa, int thread, int num)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2.f*M_PI;
+ sqr = s[1]*sqrt(2-s[1]*s[1]);
+
+ vec[0] = cos(phi)*sqr;
+ vec[1] = sin(phi)*sqr;
+ vec[2] = 1.f - s[1]*s[1];
+
+}
+
/* called from convertBlenderScene.c */
/* samples don't change per pixel, so build the samples in advance for efficiency */
void init_lamp_hammersley(LampRen *lar)
@@ -861,6 +878,20 @@ static int adaptive_sample_contrast_val(int samples, float prev, float val, floa
return 0;
}
+static float get_avg_speed(ShadeInput *shi)
+{
+ float pre_x, pre_y, post_x, post_y, speedavg;
+
+ pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0:shi->winspeed[0];
+ pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0:shi->winspeed[1];
+ post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0:shi->winspeed[2];
+ post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0:shi->winspeed[3];
+
+ speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0;
+
+ return speedavg;
+}
+
/* ***************** main calls ************** */
@@ -1407,6 +1438,7 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
float maxdist = R.wrld.aodist;
float fac=0.0f, prev=0.0f;
float adapt_thresh = G.scene->world->ao_adapt_thresh;
+ float adapt_speed_fac = G.scene->world->ao_adapt_speed_fac;
float bias = G.scene->world->aobias;
int samples=0;
@@ -1447,9 +1479,16 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
VecOrthoBasisf(nrm, up, side);
/* sampling init */
- if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON)
+ if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) {
+ float speedfac;
+
+ speedfac = get_avg_speed(shi) * adapt_speed_fac;
+ CLAMP(speedfac, 1.0, 1000.0);
+ max_samples /= speedfac;
+ if (max_samples < 5) max_samples = 5;
+
qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
- else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
+ } else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
qsa = R.qsa;
QMC_initPixel(qsa, shi->thread);
@@ -1458,7 +1497,7 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
/* sampling, returns quasi-random vector in unit hemisphere */
QMC_sampleHemi(samp3d, qsa, shi->thread, samples);
-
+
dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]);
dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]);
dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);