Code refactor: remove emission and background closures, sum directly.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 1 Nov 2017 18:00:42 +0000 (19:00 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sun, 5 Nov 2017 17:13:44 +0000 (18:13 +0100)
13 files changed:
intern/cycles/kernel/closure/emissive.h
intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_path_branched.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/kernel_volume.h
intern/cycles/kernel/osl/background.cpp
intern/cycles/kernel/osl/emissive.cpp
intern/cycles/kernel/split/kernel_indirect_background.h
intern/cycles/kernel/split/kernel_lamp_emission.h
intern/cycles/kernel/svm/svm_closure.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.h

index c534df373bdeca9ed22134bf76e4e932cb8c3a0b..e709ca9a3724c9a137492ad973c9ca90d5a169e4 100644 (file)
 
 CCL_NAMESPACE_BEGIN
 
+/* BACKGROUND CLOSURE */
+
+ccl_device void background_setup(ShaderData *sd, const float3 weight)
+{
+       if(sd->flag & SD_EMISSION) {
+               sd->closure_emission_background += weight;
+       }
+       else {
+               sd->flag |= SD_EMISSION;
+               sd->closure_emission_background = weight;
+       }
+}
+
 /* EMISSION CLOSURE */
 
+ccl_device void emission_setup(ShaderData *sd, const float3 weight)
+{
+       if(sd->flag & SD_EMISSION) {
+               sd->closure_emission_background += weight;
+       }
+       else {
+               sd->flag |= SD_EMISSION;
+               sd->closure_emission_background = weight;
+       }
+}
+
 /* return the probability distribution function in the direction I,
  * given the parameters and the light's surface normal.  This MUST match
  * the PDF computed by sample(). */
index e664a2e9dbd4fa93fa215e94144655ded862fe3e..1099064038bcd4faa43c2365212f0e1caab278db 100644 (file)
@@ -132,7 +132,7 @@ ccl_device_forceinline void kernel_path_background(
        ccl_addr_space PathState *state,
        ccl_addr_space Ray *ray,
        float3 throughput,
-       ShaderData *emission_sd,
+       ShaderData *sd,
        PathRadiance *L)
 {
        /* eval background shader if nothing hit */
@@ -153,7 +153,7 @@ ccl_device_forceinline void kernel_path_background(
 
 #ifdef __BACKGROUND__
        /* sample background shader */
-       float3 L_background = indirect_background(kg, emission_sd, state, ray);
+       float3 L_background = indirect_background(kg, sd, state, ray);
        path_radiance_accum_background(L, state, throughput, L_background);
 #endif  /* __BACKGROUND__ */
 }
@@ -407,7 +407,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
 
                /* Find intersection with lamps and compute emission for MIS. */
-               kernel_path_lamp_emission(kg, state, ray, throughput, &isect, emission_sd, L);
+               kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L);
 
 #ifdef __VOLUME__
                /* Volume integration. */
@@ -431,7 +431,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 
                /* Shade background. */
                if(!hit) {
-                       kernel_path_background(kg, state, ray, throughput, emission_sd, L);
+                       kernel_path_background(kg, state, ray, throughput, sd, L);
                        break;
                }
                else if(path_state_ao_bounce(kg, state)) {
index 42df7e85b41bc89ef928fb68f4e6005d71a208af..3877e4f00589353e19ac80d77af76b94625f0b05 100644 (file)
@@ -466,7 +466,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
 
                /* Shade background. */
                if(!hit) {
-                       kernel_path_background(kg, &state, &ray, throughput, &emission_sd, L);
+                       kernel_path_background(kg, &state, &ray, throughput, &sd, L);
                        break;
                }
 
index b410785d7e072258fe33a926d08fdb5ed9336d5c..30195605f2ebfd3b7c4294c09b9c6468838fc162 100644 (file)
@@ -926,24 +926,14 @@ ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_b
 
 /* Emission */
 
-ccl_device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
-{
-       return emissive_simple_eval(sd->Ng, sd->I);
-}
-
 ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
 {
-       float3 eval;
-       eval = make_float3(0.0f, 0.0f, 0.0f);
-
-       for(int i = 0; i < sd->num_closure; i++) {
-               ShaderClosure *sc = &sd->closure[i];
-
-               if(CLOSURE_IS_EMISSION(sc->type))
-                       eval += emissive_eval(kg, sd, sc)*sc->weight;
+       if(sd->flag & SD_EMISSION) {
+               return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
+       }
+       else {
+               return make_float3(0.0f, 0.0f, 0.0f);
        }
-
-       return eval;
 }
 
 /* Holdout */
@@ -1011,16 +1001,12 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd,
                svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
        }
 
-       float3 eval = make_float3(0.0f, 0.0f, 0.0f);
-
-       for(int i = 0; i < sd->num_closure; i++) {
-               const ShaderClosure *sc = &sd->closure[i];
-
-               if(CLOSURE_IS_BACKGROUND(sc->type))
-                       eval += sc->weight;
+       if(sd->flag & SD_EMISSION) {
+               return sd->closure_emission_background;
+       }
+       else {
+               return make_float3(0.0f, 0.0f, 0.0f);
        }
-
-       return eval;
 #else  /* __SVM__ */
        return make_float3(0.8f, 0.8f, 0.8f);
 #endif  /* __SVM__ */
index d1733d8a6e712e4303a7714777b1f49f693964d1..acd06b57a814b08e123882724eaa7676c7ace714 100644 (file)
@@ -812,7 +812,7 @@ enum ShaderDataFlag {
 
        /* Set when ray hits backside of surface. */
        SD_BACKFACING      = (1 << 0),
-       /* Shader has emissive closure. */
+       /* Shader has non-zero emission. */
        SD_EMISSION        = (1 << 1),
        /* Shader has BSDF closure. */
        SD_BSDF            = (1 << 2),
@@ -970,16 +970,6 @@ typedef ccl_addr_space struct ShaderData {
        Transform ob_itfm;
 #endif
 
-       /* Closure data, we store a fixed array of closures */
-       struct ShaderClosure closure[MAX_CLOSURE];
-       int num_closure;
-       int num_closure_extra;
-       float randb_closure;
-       float3 svm_closure_weight;
-
-       /* LCG state for closures that require additional random numbers. */
-       uint lcg_state;
-
        /* ray start position, only set for backgrounds */
        float3 ray_P;
        differential3 ray_dP;
@@ -988,6 +978,22 @@ typedef ccl_addr_space struct ShaderData {
        struct KernelGlobals *osl_globals;
        struct PathState *osl_path_state;
 #endif
+
+       /* LCG state for closures that require additional random numbers. */
+       uint lcg_state;
+
+       /* Closure data, we store a fixed array of closures */
+       int num_closure;
+       int num_closure_extra;
+       float randb_closure;
+       float3 svm_closure_weight;
+
+       /* Closure weights summed directly, so we can evaluate
+        * emission and shadow transparency with MAX_CLOSURE 0. */
+       float3 closure_emission_background;
+
+       /* At the end so we can adjust size in ShaderDataTinyStorage. */
+       struct ShaderClosure closure[MAX_CLOSURE];
 } ShaderData;
 
 /* Path State */
index 5905fb3bf12b7857ddb42b0f6d2e659dcf1a3a56..657417e16420e8e310750898a54b369316d254c7 100644 (file)
@@ -76,15 +76,14 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals *kg,
        
        coeff->sigma_a = make_float3(0.0f, 0.0f, 0.0f);
        coeff->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
-       coeff->emission = make_float3(0.0f, 0.0f, 0.0f);
+       coeff->emission = (sd->flag & SD_EMISSION)? sd->closure_emission_background:
+                                                   make_float3(0.0f, 0.0f, 0.0f);
 
        for(int i = 0; i < sd->num_closure; i++) {
                const ShaderClosure *sc = &sd->closure[i];
 
                if(sc->type == CLOSURE_VOLUME_ABSORPTION_ID)
                        coeff->sigma_a += sc->weight;
-               else if(sc->type == CLOSURE_EMISSION_ID)
-                       coeff->emission += sc->weight;
                else if(CLOSURE_IS_VOLUME(sc->type))
                        coeff->sigma_s += sc->weight;
        }
index 2e73e7a601e99aa6985047dde7ca3406b2240c4d..8fff19407d98efb3b11a9bcba3077c6604776385 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "kernel/kernel_compat_cpu.h"
 #include "kernel/closure/alloc.h"
+#include "kernel/closure/emissive.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -53,7 +54,7 @@ class GenericBackgroundClosure : public CClosurePrimitive {
 public:
        void setup(ShaderData *sd, int /* path_flag */, float3 weight)
        {
-               closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_BACKGROUND_ID, weight);
+               background_setup(sd, weight);
        }
 };
 
index 8843a196dad327f1e50f0c77c2fe37cd11ff3db9..6162786b527663bfc94bc3e9b99012d39d378d1e 100644 (file)
@@ -56,8 +56,7 @@ class GenericEmissiveClosure : public CClosurePrimitive {
 public:
        void setup(ShaderData *sd, int /* path_flag */, float3 weight)
        {
-               closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_EMISSION_ID, weight);
-               sd->flag |= SD_EMISSION;
+               emission_setup(sd, weight);
        }
 };
 
index 437043a59717d26245173da3670b15da86a1ca7e..0c894bd3d71486b889abca996e0198d97cd6e25d 100644 (file)
@@ -55,9 +55,9 @@ ccl_device void kernel_indirect_background(KernelGlobals *kg)
                PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
                ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
                float3 throughput = kernel_split_state.throughput[ray_index];
-               ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
+               ShaderData *sd = &kernel_split_state.sd[ray_index];
 
-               kernel_path_background(kg, state, ray, throughput, emission_sd, L);
+               kernel_path_background(kg, state, ray, throughput, sd, L);
                kernel_split_path_end(kg, ray_index);
        }
 }
index 448456d167d689aa25d56b2629b10db3d90a01da..d5099ac66e664ffc8c0e0cc7bac47954a68d0e2b 100644 (file)
@@ -58,9 +58,9 @@ ccl_device void kernel_lamp_emission(KernelGlobals *kg)
                float3 throughput = kernel_split_state.throughput[ray_index];
                Ray ray = kernel_split_state.ray[ray_index];
                ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
-               ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
+               ShaderData *sd = &kernel_split_state.sd[ray_index];
 
-               kernel_path_lamp_emission(kg, state, &ray, throughput, isect, emission_sd, L);
+               kernel_path_lamp_emission(kg, state, &ray, throughput, isect, sd, L);
        }
 }
 
index 4268813b2633dfdd9fd42595b2258f60c7f206b1..f1ed9af1064122d47f5d5077614eed5fe337ef66 100644 (file)
@@ -863,6 +863,7 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
 ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
 {
        uint mix_weight_offset = node.y;
+       float3 weight = sd->svm_closure_weight;
 
        if(stack_valid(mix_weight_offset)) {
                float mix_weight = stack_load_float(stack, mix_weight_offset);
@@ -870,17 +871,16 @@ ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 no
                if(mix_weight == 0.0f)
                        return;
 
-               closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_EMISSION_ID, sd->svm_closure_weight * mix_weight);
+               weight *= mix_weight;
        }
-       else
-               closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_EMISSION_ID, sd->svm_closure_weight);
 
-       sd->flag |= SD_EMISSION;
+       emission_setup(sd, weight);
 }
 
 ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
 {
        uint mix_weight_offset = node.y;
+       float3 weight = sd->svm_closure_weight;
 
        if(stack_valid(mix_weight_offset)) {
                float mix_weight = stack_load_float(stack, mix_weight_offset);
@@ -888,10 +888,10 @@ ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4
                if(mix_weight == 0.0f)
                        return;
 
-               closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_BACKGROUND_ID, sd->svm_closure_weight * mix_weight);
+               weight *= mix_weight;
        }
-       else
-               closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_BACKGROUND_ID, sd->svm_closure_weight);
+
+       background_setup(sd, weight);
 }
 
 ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
index 7fb82bc502aee3d1229f9494479d9a869e388745..e81c9a211b0e3dbf0027212688b2125b506070fb 100644 (file)
@@ -445,8 +445,6 @@ typedef enum ClosureType {
        CLOSURE_BSSRDF_BURLEY_ID,
 
        /* Other */
-       CLOSURE_EMISSION_ID,
-       CLOSURE_BACKGROUND_ID,
        CLOSURE_HOLDOUT_ID,
        CLOSURE_AMBIENT_OCCLUSION_ID,
 
@@ -478,9 +476,7 @@ typedef enum ClosureType {
 #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
 #define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
 #define CLOSURE_IS_VOLUME_ABSORPTION(type) (type == CLOSURE_VOLUME_ABSORPTION_ID)
-#define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
 #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
-#define CLOSURE_IS_BACKGROUND(type) (type == CLOSURE_BACKGROUND_ID)
 #define CLOSURE_IS_AMBIENT_OCCLUSION(type) (type == CLOSURE_AMBIENT_OCCLUSION_ID)
 #define CLOSURE_IS_PHASE(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
 #define CLOSURE_IS_GLASS(type) (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID)
index 4ec485d521b124cdc3b8e7f8bfc8d8feff1681b7..3b8a8bcd4b552b44d1ca7628fda580a2f2f3110f 100644 (file)
@@ -476,7 +476,6 @@ class EmissionNode : public ShaderNode {
 public:
        SHADER_NODE_CLASS(EmissionNode)
        void constant_fold(const ConstantFolder& folder);
-       virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; }
 
        bool has_surface_emission() { return true; }
        bool has_volume_support() { return true; }
@@ -490,7 +489,6 @@ class BackgroundNode : public ShaderNode {
 public:
        SHADER_NODE_CLASS(BackgroundNode)
        void constant_fold(const ConstantFolder& folder);
-       virtual ClosureType get_closure_type() { return CLOSURE_BACKGROUND_ID; }
 
        float3 color;
        float strength;