Code cleanup: remove hack to avoid seeing transparent objects in noise.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 14 Sep 2017 19:53:00 +0000 (21:53 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 20 Sep 2017 17:38:08 +0000 (19:38 +0200)
Previously the Sobol pattern suffered from some correlation issues that
made the outline of objects like a smoke domain visible. This helps
simplify the code and also makes some other optimizations possible.

intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_path_branched.h
intern/cycles/kernel/kernel_path_state.h
intern/cycles/kernel/kernel_path_volume.h
intern/cycles/kernel/kernel_random.h
intern/cycles/kernel/kernel_volume.h
intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
intern/cycles/kernel/split/kernel_shader_eval.h

index 3a242a0..2c79f58 100644 (file)
@@ -210,8 +210,8 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
                                /* indirect sample. if we use distance sampling and take just
                                 * one sample for direct and indirect light, we could share
                                 * this computation, but makes code a bit complex */
-                               float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
-                               float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
+                               float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
+                               float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
 
                                result = kernel_volume_decoupled_scatter(kg,
                                        state, &volume_ray, sd, throughput,
@@ -434,7 +434,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                                      sd,
                                      &isect,
                                      ray);
-               float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
+               float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
                shader_eval_surface(kg, sd, state, rbsdf, state->flag);
 #ifdef __BRANCHED_PATH__
                shader_merge_closures(sd);
@@ -462,7 +462,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                        break;
                }
                else if(probability != 1.0f) {
-                       float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
+                       float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
 
                        if(terminate >= probability)
                                break;
@@ -591,7 +591,7 @@ ccl_device_forceinline void kernel_path_integrate(
 
                /* Setup and evaluate shader. */
                shader_setup_from_ray(kg, &sd, &isect, ray);
-               float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
+               float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
                shader_eval_surface(kg, &sd, state, rbsdf, state->flag);
 
                /* Apply shadow catcher, holdout, emission. */
@@ -616,7 +616,7 @@ ccl_device_forceinline void kernel_path_integrate(
                        break;
                }
                else if(probability != 1.0f) {
-                       float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
+                       float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
                        if(terminate >= probability)
                                break;
 
index 3994d8d..e525e00 100644 (file)
@@ -339,8 +339,8 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
                                        /* scatter sample. if we use distance sampling and take just one
                                         * sample for direct and indirect light, we could share this
                                         * computation, but makes code a bit complex */
-                                       float rphase = path_state_rng_1D_for_decision(kg, &ps, PRNG_PHASE);
-                                       float rscatter = path_state_rng_1D_for_decision(kg, &ps, PRNG_SCATTER_DISTANCE);
+                                       float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE);
+                                       float rscatter = path_state_rng_1D(kg, &ps, PRNG_SCATTER_DISTANCE);
 
                                        VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
                                                &ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false);
@@ -466,7 +466,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
                                break;
                        }
                        else if(probability != 1.0f) {
-                               float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE);
+                               float terminate = path_state_rng_1D(kg, &state, PRNG_TERMINATE);
 
                                if(terminate >= probability)
                                        break;
index bb09b4a..eccee54 100644 (file)
@@ -76,12 +76,12 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta
                state->flag |= PATH_RAY_TRANSPARENT;
                state->transparent_bounce++;
 
-               /* don't increase random number generator offset here, to avoid some
-                * unwanted patterns, see path_state_rng_1D_for_decision */
-
                if(!kernel_data.integrator.transparent_shadows)
                        state->flag |= PATH_RAY_MIS_SKIP;
 
+               /* random number generator next bounce */
+               state->rng_offset += PRNG_BOUNCE_NUM;
+
                return;
        }
 
index e7e24f8..f645a10 100644 (file)
@@ -155,8 +155,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
                                float3 tp = throughput;
 
                                /* sample position on volume segment */
-                               float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
-                               float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
+                               float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
+                               float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
 
                                VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
                                        state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@@ -201,8 +201,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
                                float3 tp = throughput;
 
                                /* sample position on volume segment */
-                               float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
-                               float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
+                               float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
+                               float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
 
                                VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
                                        state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@@ -238,8 +238,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
                float3 tp = throughput;
 
                /* sample position on volume segment */
-               float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
-               float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
+               float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
+               float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
 
                VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
                        state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
index b35ed3b..eb23c77 100644 (file)
@@ -186,25 +186,6 @@ ccl_device_inline float path_state_rng_1D(KernelGlobals *kg,
                           state->rng_offset + dimension);
 }
 
-ccl_device_inline float path_state_rng_1D_for_decision(
-        KernelGlobals *kg,
-        const ccl_addr_space PathState *state,
-        int dimension)
-{
-       /* The rng_offset is not increased for transparent bounces. if we do then
-        * fully transparent objects can become subtly visible by the different
-        * sampling patterns used where the transparent object is.
-        *
-        * however for some random numbers that will determine if we next bounce
-        * is transparent we do need to increase the offset to avoid always making
-        * the same decision. */
-       const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
-       return path_rng_1D(kg,
-                          state->rng_hash,
-                          state->sample, state->num_samples,
-                          rng_offset + dimension);
-}
-
 ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
                                          const ccl_addr_space PathState *state,
                                          int dimension,
@@ -232,22 +213,6 @@ ccl_device_inline float path_branched_rng_1D(
                           state->rng_offset + dimension);
 }
 
-ccl_device_inline float path_branched_rng_1D_for_decision(
-        KernelGlobals *kg,
-        uint rng_hash,
-        const ccl_addr_space PathState *state,
-        int branch,
-        int num_branches,
-        int dimension)
-{
-       const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
-       return path_rng_1D(kg,
-                          rng_hash,
-                          state->sample * num_branches + branch,
-                          state->num_samples * num_branches,
-                          rng_offset + dimension);
-}
-
 ccl_device_inline void path_branched_rng_2D(
         KernelGlobals *kg,
         uint rng_hash,
@@ -273,7 +238,7 @@ ccl_device_inline float path_state_rng_light_termination(
         const ccl_addr_space PathState *state)
 {
        if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
-               return path_state_rng_1D_for_decision(kg, state, PRNG_LIGHT_TERMINATE);
+               return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE);
        }
        return 0.0f;
 }
@@ -286,12 +251,12 @@ ccl_device_inline float path_branched_rng_light_termination(
         int num_branches)
 {
        if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
-               return path_branched_rng_1D_for_decision(kg,
-                                                        rng_hash,
-                                                        state,
-                                                        branch,
-                                                        num_branches,
-                                                        PRNG_LIGHT_TERMINATE);
+               return path_branched_rng_1D(kg,
+                                           rng_hash,
+                                           state,
+                                           branch,
+                                           num_branches,
+                                           PRNG_LIGHT_TERMINATE);
        }
        return 0.0f;
 }
index d8e8e19..bdaba2e 100644 (file)
@@ -379,13 +379,13 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
 
                /* pick random color channel, we use the Veach one-sample
                 * model with balance heuristic for the channels */
-               float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
+               float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
                int channel = (int)(rphase*3.0f);
                sd->randb_closure = rphase*3.0f - channel;
 
                /* decide if we will hit or miss */
                bool scatter = true;
-               float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
+               float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
 
                if(probalistic_scatter) {
                        float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
@@ -483,8 +483,8 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
 
        /* pick random color channel, we use the Veach one-sample
         * model with balance heuristic for the channels */
-       float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
-       float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
+       float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
+       float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
        int channel = (int)(rphase*3.0f);
        sd->randb_closure = rphase*3.0f - channel;
        bool has_scatter = false;
index 9036b1e..4d9e08b 100644 (file)
@@ -140,7 +140,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
                        kernel_split_path_end(kg, ray_index);
                }
                else if(probability < 1.0f) {
-                       float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
+                       float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
                        if(terminate >= probability) {
                                kernel_split_path_end(kg, ray_index);
                        }
index eac29dc..20bd211 100644 (file)
@@ -51,13 +51,13 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg)
                ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
 
 #ifndef __BRANCHED_PATH__
-               float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
+               float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
                shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag);
 #else
                float rbsdf = 0.0f;
 
                if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
-                       rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
+                       rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
 
                }