svn merge -r 16866:17042 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender-staging.git] / source / blender / render / intern / source / rayshade.c
index 453e8ddcd48f19261fd9926452ba32092fccab17..c431340d770a229b37b847a8eb8e3dd533ded6f1 100644 (file)
@@ -1793,21 +1793,62 @@ void ray_ao(ShadeInput *shi, float *shadfac)
                ray_ao_spheresamp(shi, shadfac);
 }
 
+static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco)
+{
+       /* magic numbers for reordering sample positions to give better
+        * results with adaptive sample, when it usually only takes 4 samples */
+       int order8[8] = {0, 1, 5, 6, 2, 3, 4, 7};
+       int order11[11] = {1, 3, 8, 10, 0, 2, 4, 5, 6, 7, 9};
+       int order16[16] = {1, 3, 9, 12, 0, 6, 7, 8, 13, 2, 4, 5, 10, 11, 14, 15};
+       int count = count_mask(shi->mask);
+
+       /* for better antialising shadow samples are distributed over the subpixel
+        * sample coordinates, this only works for raytracing depth 0 though */
+       if(!shi->strand && shi->depth == 0 && count > 1 && count <= max) {
+               float xs, ys, zs, view[3];
+               int samp, ordsamp, tot= 0;
+
+               for(samp=0; samp<R.osa; samp++) {
+                       if(R.osa == 8) ordsamp = order8[samp];
+                       else if(R.osa == 11) ordsamp = order11[samp];
+                       else if(R.osa == 16) ordsamp = order16[samp];
+                       else ordsamp = samp;
+
+                       if(shi->mask & (1<<ordsamp)) {
+                               /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
+                               xs= (float)shi->scanco[0] + R.jit[ordsamp][0] + 0.5f;
+                               ys= (float)shi->scanco[1] + R.jit[ordsamp][1] + 0.5f;
+                               zs= shi->scanco[2];
+
+                               shade_input_calc_viewco(shi, xs, ys, zs, view, NULL, jitco[tot], NULL, NULL);
+                               tot++;
+                       }
+               }
+
+               *totjitco= tot;
+       }
+       else {
+               VECCOPY(jitco[0], shi->co);
+               *totjitco= 1;
+       }
+}
 
 static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
 {
        QMCSampler *qsa=NULL;
-       QMCSampler *qsa_jit=NULL;
        int samples=0;
-       float samp3d[3], jit[3], jitbias= 0.0f;
+       float samp3d[3];
 
        float fac=0.0f, vec[3];
        float colsq[4];
        float adapt_thresh = lar->adapt_thresh;
-       int max_samples = lar->ray_totsamp;
-       float pos[3];
+       int min_adapt_samples=4, max_samples = lar->ray_totsamp;
+       float *co;
        int do_soft=1, full_osa=0;
 
+       float jitco[RE_MAX_OSA][3];
+       int totjitco;
+
        colsq[0] = colsq[1] = colsq[2] = 0.0;
        if(isec->mode==RE_RAY_SHADOW_TRA) {
                shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
@@ -1824,21 +1865,16 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                if (do_soft) max_samples = lar->ray_totsamp;
                else max_samples = (R.osa > 4)?R.osa:5;
        }
-
-       if(shi->vlr && ((shi->vlr->flag & R_FULL_OSA) == 0))
-               jitbias= 0.5f*(VecLength(shi->dxco) + VecLength(shi->dyco));
+       
+       ray_shadow_jittered_coords(shi, max_samples, jitco, &totjitco);
 
        /* sampling init */
-       if (lar->ray_samp_method==LA_SAMP_HALTON) {
+       if (lar->ray_samp_method==LA_SAMP_HALTON)
                qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples);
-               qsa_jit = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples);
-       } else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY) {
+       else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY)
                qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
-               qsa_jit = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
-       }
        
        QMC_initPixel(qsa, shi->thread);
-       QMC_initPixel(qsa_jit, shi->thread);
        
        VECCOPY(vec, lampco);
        
@@ -1846,18 +1882,11 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
        while (samples < max_samples) {
                isec->faceorig= (RayFace*)shi->vlr;
                isec->oborig= RAY_OBJECT_SET(&R, shi->obi);
-               
+
                /* manually jitter the start shading co-ord per sample
                 * based on the pre-generated OSA texture sampling offsets, 
                 * for anti-aliasing sharp shadow edges. */
-               VECCOPY(pos, shi->co);
-               if (shi->vlr && !full_osa) {
-                       QMC_sampleRect(jit, qsa_jit, shi->thread, samples, 1.0, 1.0);
-                       
-                       pos[0] += shi->dxco[0]*jit[0] + shi->dyco[0]*jit[1];
-                       pos[1] += shi->dxco[1]*jit[0] + shi->dyco[1]*jit[1];
-                       pos[2] += shi->dxco[2]*jit[0] + shi->dyco[2]*jit[1];
-               }
+               co = jitco[samples % totjitco];
 
                if (do_soft) {
                        /* sphere shadow source */
@@ -1865,9 +1894,9 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                                float ru[3], rv[3], v[3], s[3];
                                
                                /* calc tangent plane vectors */
-                               v[0] = pos[0] - lampco[0];
-                               v[1] = pos[1] - lampco[1];
-                               v[2] = pos[2] - lampco[2];
+                               v[0] = co[0] - lampco[0];
+                               v[1] = co[1] - lampco[1];
+                               v[2] = co[2] - lampco[2];
                                Normalize(v);
                                VecOrthoBasisf(v, ru, rv);
                                
@@ -1880,13 +1909,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                                s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2];
                                
                                VECCOPY(samp3d, s);
-
-                               if(jitbias != 0.0f) {
-                                       /* bias away somewhat to avoid self intersection */
-                                       pos[0] -= jitbias*v[0];
-                                       pos[1] -= jitbias*v[1];
-                                       pos[2] -= jitbias*v[2];
-                               }
                        }
                        else {
                                /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */
@@ -1902,20 +1924,20 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                        VECCOPY(isec->end, vec);
                }
 
-               if(jitbias != 0.0f && !(do_soft && lar->type==LA_LOCAL)) {
+               if(shi->strand) {
                        /* bias away somewhat to avoid self intersection */
+                       float jitbias= 0.5f*(VecLength(shi->dxco) + VecLength(shi->dyco));
                        float v[3];
 
-                       VECSUB(v, pos, isec->end);
+                       VECSUB(v, co, isec->end);
                        Normalize(v);
 
-                       pos[0] -= jitbias*v[0];
-                       pos[1] -= jitbias*v[1];
-                       pos[2] -= jitbias*v[2];
+                       co[0] -= jitbias*v[0];
+                       co[1] -= jitbias*v[1];
+                       co[2] -= jitbias*v[2];
                }
 
-               VECCOPY(isec->start, pos);
-               
+               VECCOPY(isec->start, co);
                
                /* trace the ray */
                if(isec->mode==RE_RAY_SHADOW_TRA) {
@@ -1942,7 +1964,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                if ((lar->ray_samp_method == LA_SAMP_HALTON)) {
                
                        /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */
-                       if ((max_samples > 4) && (adapt_thresh > 0.0) && (samples > max_samples / 3)) {
+                       if ((max_samples > min_adapt_samples) && (adapt_thresh > 0.0) && (samples > max_samples / 3)) {
                                if (isec->mode==RE_RAY_SHADOW_TRA) {
                                        if ((shadfac[3] / samples > (1.0-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh))
                                                break;
@@ -1964,8 +1986,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
        } else
                shadfac[3]= 1.0f-fac/samples;
 
-       if (qsa_jit)
-               release_thread_qmcsampler(&R, shi->thread, qsa_jit);
        if (qsa)
                release_thread_qmcsampler(&R, shi->thread, qsa);
 }