From 2c02a04c464c2f5c6e211ceb7b21255eaca7e087 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 1 Nov 2017 19:00:42 +0100 Subject: Code refactor: remove emission and background closures, sum directly. --- intern/cycles/kernel/closure/emissive.h | 24 +++++++++++++++ intern/cycles/kernel/kernel_path.h | 8 ++--- intern/cycles/kernel/kernel_path_branched.h | 2 +- intern/cycles/kernel/kernel_shader.h | 34 +++++++--------------- intern/cycles/kernel/kernel_types.h | 28 +++++++++++------- intern/cycles/kernel/kernel_volume.h | 5 ++-- intern/cycles/kernel/osl/background.cpp | 3 +- intern/cycles/kernel/osl/emissive.cpp | 3 +- .../kernel/split/kernel_indirect_background.h | 4 +-- intern/cycles/kernel/split/kernel_lamp_emission.h | 4 +-- intern/cycles/kernel/svm/svm_closure.h | 14 ++++----- intern/cycles/kernel/svm/svm_types.h | 4 --- intern/cycles/render/nodes.h | 2 -- 13 files changed, 72 insertions(+), 63 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h index c534df373bd..e709ca9a372 100644 --- a/intern/cycles/kernel/closure/emissive.h +++ b/intern/cycles/kernel/closure/emissive.h @@ -32,8 +32,32 @@ 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(). */ diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index e664a2e9dbd..1099064038b 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -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)) { diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 42df7e85b41..3877e4f0058 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -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; } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index b410785d7e0..30195605f2e 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -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__ */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index d1733d8a6e7..acd06b57a81 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -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 */ diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 5905fb3bf12..657417e1642 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -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; } diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 2e73e7a601e..8fff19407d9 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -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); } }; diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 8843a196dad..6162786b527 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -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); } }; diff --git a/intern/cycles/kernel/split/kernel_indirect_background.h b/intern/cycles/kernel/split/kernel_indirect_background.h index 437043a5971..0c894bd3d71 100644 --- a/intern/cycles/kernel/split/kernel_indirect_background.h +++ b/intern/cycles/kernel/split/kernel_indirect_background.h @@ -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); } } diff --git a/intern/cycles/kernel/split/kernel_lamp_emission.h b/intern/cycles/kernel/split/kernel_lamp_emission.h index 448456d167d..d5099ac66e6 100644 --- a/intern/cycles/kernel/split/kernel_lamp_emission.h +++ b/intern/cycles/kernel/split/kernel_lamp_emission.h @@ -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); } } diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 4268813b263..f1ed9af1064 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -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) diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 7fb82bc502a..e81c9a211b0 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -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) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 4ec485d521b..3b8a8bcd4b5 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -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; -- cgit v1.2.3