Commit: b3afc8917cdeaa98ebfa3f2aa17e8c5a69fdb1e3
Author: Brecht Van Lommel
Date:   Fri Sep 15 01:55:44 2017 +0200
Branches: master
https://developer.blender.org/rBb3afc8917cdeaa98ebfa3f2aa17e8c5a69fdb1e3

Code cleanup: refactor BSSRDF closure sampling, for next commit.

===================================================================

M       intern/cycles/kernel/closure/bssrdf.h
M       intern/cycles/kernel/kernel_path.h
M       intern/cycles/kernel/kernel_path_subsurface.h
M       intern/cycles/kernel/kernel_shader.h
M       intern/cycles/kernel/kernel_subsurface.h
M       intern/cycles/kernel/split/kernel_subsurface_scatter.h

===================================================================

diff --git a/intern/cycles/kernel/closure/bssrdf.h 
b/intern/cycles/kernel/closure/bssrdf.h
index 06221189060..267aeea6e86 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -400,7 +400,7 @@ ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType 
type)
                        bssrdf_burley_setup(bssrdf);
                }
 
-               return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF;
+               return SD_BSSRDF;
        }
 }
 
diff --git a/intern/cycles/kernel/kernel_path.h 
b/intern/cycles/kernel/kernel_path.h
index 2c79f5892e6..86b2aa00776 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -483,11 +483,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                /* bssrdf scatter to a different location on the same object, 
replacing
                 * the closures with a diffuse BSDF */
                if(sd->flag & SD_BSSRDF) {
-                       float bssrdf_probability;
-                       ShaderClosure *sc = subsurface_scatter_pick_closure(kg, 
sd, &bssrdf_probability);
-
-                       /* modify throughput for picking bssrdf or bsdf */
-                       throughput *= bssrdf_probability;
+                       const ShaderClosure *sc = shader_bssrdf_pick(sd, 
&throughput);
 
                        /* do bssrdf scatter step if we picked a bssrdf closure 
*/
                        if(sc) {
diff --git a/intern/cycles/kernel/kernel_path_subsurface.h 
b/intern/cycles/kernel/kernel_path_subsurface.h
index 619d57e71fb..cc6231eb6b1 100644
--- a/intern/cycles/kernel/kernel_path_subsurface.h
+++ b/intern/cycles/kernel/kernel_path_subsurface.h
@@ -32,11 +32,7 @@ bool kernel_path_subsurface_scatter(
         ccl_addr_space float3 *throughput,
         ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
 {
-       float bssrdf_probability;
-       ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, 
&bssrdf_probability);
-
-       /* modify throughput for picking bssrdf or bsdf */
-       *throughput *= bssrdf_probability;
+       const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput);
 
        /* do bssrdf scatter step if we picked a bssrdf closure */
        if(sc) {
diff --git a/intern/cycles/kernel/kernel_shader.h 
b/intern/cycles/kernel/kernel_shader.h
index 5964aca0c78..88aa1f712a4 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -497,17 +497,14 @@ ccl_device_inline void shader_merge_closures(ShaderData 
*sd)
 /* BSDF */
 
 ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, ShaderData 
*sd, const float3 omega_in, float *pdf,
-       int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float 
sum_sample_weight)
+       const ShaderClosure *skip_sc, BsdfEval *result_eval, float sum_pdf, 
float sum_sample_weight)
 {
        /* this is the veach one-sample model with balance heuristic, some pdf
         * factors drop out when using balance heuristic weighting */
        for(int i = 0; i < sd->num_closure; i++) {
-               if(i == skip_bsdf)
-                       continue;
-
                const ShaderClosure *sc = &sd->closure[i];
 
-               if(CLOSURE_IS_BSDF(sc->type)) {
+               if(sc != skip_sc && CLOSURE_IS_BSDF(sc->type)) {
                        float bsdf_pdf = 0.0f;
                        float3 eval = bsdf_eval(kg, sd, sc, omega_in, 
&bsdf_pdf);
 
@@ -570,7 +567,7 @@ void shader_bsdf_eval(KernelGlobals *kg,
 #endif
        {
                float pdf;
-               _shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, -1, eval, 0.0f, 
0.0f);
+               _shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, NULL, eval, 
0.0f, 0.0f);
                if(use_mis) {
                        float weight = power_heuristic(light_pdf, pdf);
                        bsdf_eval_mis(eval, weight);
@@ -578,48 +575,106 @@ void shader_bsdf_eval(KernelGlobals *kg,
        }
 }
 
-ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
-                                         ShaderData *sd,
-                                         float randu, float randv,
-                                         BsdfEval *bsdf_eval,
-                                         float3 *omega_in,
-                                         differential3 *domega_in,
-                                         float *pdf)
+ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd)
 {
        int sampled = 0;
 
        if(sd->num_closure > 1) {
-               /* pick a BSDF closure based on sample weights */
+               /* Pick a BSDF or based on sample weights. */
                float sum = 0.0f;
 
-               for(sampled = 0; sampled < sd->num_closure; sampled++) {
-                       const ShaderClosure *sc = &sd->closure[sampled];
-                       
-                       if(CLOSURE_IS_BSDF(sc->type))
+               for(int i = 0; i < sd->num_closure; i++) {
+                       const ShaderClosure *sc = &sd->closure[i];
+
+                       if(CLOSURE_IS_BSDF(sc->type)) {
                                sum += sc->sample_weight;
+                       }
                }
 
                float r = sd->randb_closure*sum;
-               sum = 0.0f;
+               float partial_sum = 0.0f;
+
+               for(int i = 0; i < sd->num_closure; i++) {
+                       const ShaderClosure *sc = &sd->closure[i];
 
-               for(sampled = 0; sampled < sd->num_closure; sampled++) {
-                       const ShaderClosure *sc = &sd->closure[sampled];
-                       
                        if(CLOSURE_IS_BSDF(sc->type)) {
-                               sum += sc->sample_weight;
+                               partial_sum += sc->sample_weight;
 
-                               if(r <= sum)
+                               if(r <= partial_sum) {
+                                       sampled = i;
                                        break;
+                               }
                        }
                }
+       }
 
-               if(sampled == sd->num_closure) {
-                       *pdf = 0.0f;
-                       return LABEL_NONE;
+       return &sd->closure[sampled];
+}
+
+ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
+                                                          ccl_addr_space 
float3 *throughput)
+{
+       int sampled = 0;
+
+       if(sd->num_closure > 1) {
+               /* Pick a BSDF or BSSRDF or based on sample weights. */
+               float sum_bsdf = 0.0f;
+               float sum_bssrdf = 0.0f;
+
+               for(int i = 0; i < sd->num_closure; i++) {
+                       const ShaderClosure *sc = &sd->closure[i];
+
+                       if(CLOSURE_IS_BSDF(sc->type)) {
+                               sum_bsdf += sc->sample_weight;
+                       }
+                       else if(CLOSURE_IS_BSSRDF(sc->type)) {
+                               sum_bssrdf += sc->sample_weight;
+                       }
+               }
+
+               float r = sd->randb_closure*(sum_bsdf + sum_bssrdf);
+               float partial_sum = 0.0f;
+
+               for(int i = 0; i < sd->num_closure; i++) {
+                       const ShaderClosure *sc = &sd->closure[i];
+
+                       if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
+                               partial_sum += sc->sample_weight;
+
+                               if(r <= partial_sum) {
+                                       if(CLOSURE_IS_BSDF(sc->type)) {
+                                               *throughput *= (sum_bsdf + 
sum_bssrdf) / sum_bsdf;
+                                               return NULL;
+                                       }
+                                       else {
+                                               *throughput *= (sum_bsdf + 
sum_bssrdf) / sum_bssrdf;
+                                               sampled = i;
+                                               break;
+                                       }
+                               }
+                       }
                }
        }
 
-       const ShaderClosure *sc = &sd->closure[sampled];
+       return &sd->closure[sampled];
+}
+
+ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
+                                         ShaderData *sd,
+                                         float randu, float randv,
+                                         BsdfEval *bsdf_eval,
+                                         float3 *omega_in,
+                                         differential3 *domega_in,
+                                         float *pdf)
+{
+       const ShaderClosure *sc = shader_bsdf_pick(sd);
+       if(!sc) {
+               *pdf = 0.0f;
+               return LABEL_NONE;
+       }
+
+       /* BSSRDF should already have been handled elsewhere. */
+       kernel_assert(CLOSURE_IS_BSDF(sc->type));
 
        int label;
        float3 eval;
@@ -632,7 +687,7 @@ ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
 
                if(sd->num_closure > 1) {
                        float sweight = sc->sample_weight;
-                       _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, 
sampled, bsdf_eval, *pdf*sweight, sweight);
+                       _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, 
bsdf_eval, *pdf*sweight, sweight);
                }
        }
 
diff --git a/intern/cycles/kernel/kernel_subsurface.h 
b/intern/cycles/kernel/kernel_subsurface.h
index 26ec6383b73..027d59b5a4e 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -28,87 +28,31 @@ CCL_NAMESPACE_BEGIN
  * - try to reduce one sample model variance
  */
 
-#define BSSRDF_MULTI_EVAL
-
-ccl_device ShaderClosure *subsurface_scatter_pick_closure(KernelGlobals *kg, 
ShaderData *sd, float *probability)
-{
-       /* sum sample weights of bssrdf and bsdf */
-       float bsdf_sum = 0.0f;
-       float bssrdf_sum = 0.0f;
-
-       for(int i = 0; i < sd->num_closure; i++) {
-               ShaderClosure *sc = &sd->closure[i];
-               
-               if(CLOSURE_IS_BSDF(sc->type))
-                       bsdf_sum += sc->sample_weight;
-               else if(CLOSURE_IS_BSSRDF(sc->type))
-                       bssrdf_sum += sc->sample_weight;
-       }
-
-       /* use bsdf or bssrdf? */
-       float r = sd->randb_closure*(bsdf_sum + bssrdf_sum);
-
-       if(r < bsdf_sum) {
-               /* use bsdf, and adjust randb so we can reuse it for picking a 
bsdf */
-               sd->randb_closure = r/bsdf_sum;
-               *probability = (bsdf_sum > 0.0f)? (bsdf_sum + 
bssrdf_sum)/bsdf_sum: 1.0f;
-               return NULL;
-       }
-
-       /* use bssrdf */
-       r -= bsdf_sum;
-
-       float sum = 0.0f;
-
-       for(int i = 0; i < sd->num_closure; i++) {
-               ShaderClosure *sc = &sd->closure[i];
-               
-               if(CLOSURE_IS_BSSRDF(sc->type)) {
-                       sum += sc->sample_weight;
-
-                       if(r <= sum) {
-                               sd->randb_closure = (r - (sum - 
sc->sample_weight))/sc->sample_weight;
-
-#ifdef BSSRDF_MULTI_EVAL
-                               *probability = (bssrdf_sum > 0.0f)? (bsdf_sum + 
bssrdf_sum)/bssrdf_sum: 1.0f;
-#else
-                               *probability = (bssrdf_sum > 0.0f)? (bsdf_sum + 
bssrdf_sum)/sc->sample_weight: 1.0f;
-#endif
-                               return sc;
-                       }
-               }
-       }
-
-       /* should never happen */
-       sd->randb_closure = 0.0f;
-       *probability = 1.0f;
-       return NULL;
-}
-
 ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd,
-                                                 ShaderClosure *sc,
+                                                 const ShaderClosure *sc,
                                                  float disk_r,
                                                  float r,
                                                  bool all)
 {
-#ifdef BSSRDF_MULTI_EVAL
        /* this is the veach one-sample model with balance heuristic, some pdf
         * factors drop out when using balance heuristic weighting */
        float3 eval_sum = make_float3(0.0f, 0.0f, 0.0f);
        float pdf_sum = 0.0f;
-       float sample_weight_sum = 0.0f;
-       int num_bssrdf = 0;
+       float sample_weight_inv = 0.0f;
 
-       for(int i = 0; i < sd->num_closure; i++) {
-               sc = &sd->closure[i];
-               
-               if(CLOSURE_IS_BSSRDF(sc->type)) {
-                       float sample_weight = (all)? 1.0f: sc->sample_weight;
-                       sample_weight_sum += sample_weight;
+       if(!all) {
+               float sample_weight_sum = 0.0f;
+
+               for(int i = 0; i < sd->num_closure; i++) {
+                       sc = &sd->closure[i];
+
+                       if(CLOSURE_IS_BSSRDF(sc->type)) {
+                               sample_weight_sum += sc->sample_weig

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to