diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 6c001f8889b..431796e106b 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -304,7 +304,8 @@ static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node) xml_read_int(&integrator->volume_max_steps, node, "volume_max_steps"); /* Various Settings */ - xml_read_bool(&integrator->no_caustics, node, "no_caustics"); + xml_read_bool(&integrator->caustics_reflective, node, "caustics_reflective"); + xml_read_bool(&integrator->caustics_refractive, node, "caustics_refractive"); xml_read_float(&integrator->filter_glossy, node, "filter_glossy"); xml_read_int(&integrator->seed, node, "seed"); diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index f3885b442ec..93f7b1d6abf 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -259,11 +259,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=True, ) - cls.no_caustics = BoolProperty( - name="No Caustics", - description="Leave out caustics, resulting in a darker image with less noise", - default=False, + cls.caustics_reflective = BoolProperty( + name="Reflective Caustics", + description="Leave out reflective caustics, resulting in a darker image with less noise", + default=True, ) + + cls.caustics_refractive = BoolProperty( + name="Refractive Caustics", + description="Leave out refractive caustics, resulting in a darker image with less noise", + default=True, + ) + cls.blur_glossy = FloatProperty( name="Filter Glossy", description="Adaptively blur glossy shaders after blurry bounces, " diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 198926e2536..6e40c42fb2d 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -210,7 +210,8 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel): col.separator() - col.prop(cscene, "no_caustics") + col.prop(cscene, "caustics_reflective") + col.prop(cscene, "caustics_refractive") col.prop(cscene, "blur_glossy") col = split.column() diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index b0b4e1d24dd..20973907693 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -33,3 +33,15 @@ def do_versions(self): cscene = scene.cycles if not cscene.is_property_set("volume_bounces"): cscene.volume_bounces = 1 + + for scene in bpy.data.scenes: + cscene = scene.cycles + try: + if (cscene["no_caustics"] and + not cscene.is_property_set("caustics_reflective") and + not cscene.is_property_set("caustics_refractive")): + + cscene.caustics_reflective = False + cscene.caustics_refractive = False + except KeyError: + pass diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index a5d6bdf1fa1..2ac90b34fd7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -180,7 +180,8 @@ void BlenderSync::sync_integrator() integrator->volume_max_steps = get_int(cscene, "volume_max_steps"); integrator->volume_step_size = get_float(cscene, "volume_step_size"); - integrator->no_caustics = get_boolean(cscene, "no_caustics"); + integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective"); + integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive"); integrator->filter_glossy = get_float(cscene, "blur_glossy"); integrator->seed = get_int(cscene, "seed"); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 489a1c26972..933202ea498 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -874,7 +874,8 @@ typedef struct KernelIntegrator { int transparent_shadows; /* caustics */ - int no_caustics; + int caustics_reflective; + int caustics_refractive; float filter_glossy; /* seed */ diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 6311be6bfcc..d7789edcfff 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -105,7 +105,7 @@ BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LA CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0), BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) -BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, ashikhmin_shirley, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, ashikhmin_shirley, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.N), CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.T), CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data0), @@ -124,37 +124,37 @@ BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, glossy_toon, LABEL_GLOSSY) CLOSURE_FLOAT_PARAM(GlossyToonClosure, sc.data1), BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0), BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, microfacet_ggx, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, microfacet_ggx, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.N), CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.T), CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data1), BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0), BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, microfacet_beckmann, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, microfacet_beckmann, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.N), CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.T), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data1), BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY|LABEL_TRANSMIT) CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data2), BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY) +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY|LABEL_TRANSMIT) CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data2), diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 28135784db9..48498116874 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -164,11 +164,14 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, CBSDFClosure *bsdf = (CBSDFClosure *)prim; int scattering = bsdf->scattering(); - /* no caustics option */ - if(scattering == LABEL_GLOSSY && (path_flag & PATH_RAY_DIFFUSE)) { + /* caustic options */ + if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { KernelGlobals *kg = sd->osl_globals; - if(kernel_data.integrator.no_caustics) + + if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { return; + } } /* sample weight */ diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index cd6d9fc53b5..30110db3ef9 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -179,7 +179,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; #endif ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); @@ -207,7 +207,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; #endif ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); @@ -244,8 +244,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_reflective && + !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) { break; + } #endif /* index of refraction */ float eta = fmaxf(param2, 1e-5f); @@ -262,12 +264,21 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float sample_weight = sc->sample_weight; sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); - - if(sc) { - sc->N = N; - svm_node_glass_setup(sd, sc, type, eta, roughness, false); +#ifdef __CAUSTICS_TRICKS__ + if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) +#endif + { + if(sc) { + sc->N = N; + svm_node_glass_setup(sd, sc, type, eta, roughness, false); + } } +#ifdef __CAUSTICS_TRICKS__ + if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) + break; +#endif + /* refraction */ sc = &sd->closure[sd->num_closure]; sc->weight = weight; @@ -286,7 +297,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) + if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; #endif ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 32e887d48f1..b7a87ac14da 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -43,7 +43,8 @@ Integrator::Integrator() volume_max_steps = 1024; volume_step_size = 0.1f; - no_caustics = false; + caustics_reflective = true; + caustics_refractive = true; filter_glossy = 0.0f; seed = 0; layer_flag = ~0; @@ -100,7 +101,8 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->volume_max_steps = volume_max_steps; kintegrator->volume_step_size = volume_step_size; - kintegrator->no_caustics = no_caustics; + kintegrator->caustics_reflective = caustics_reflective; + kintegrator->caustics_refractive = caustics_refractive; kintegrator->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy; kintegrator->seed = hash_int(seed); @@ -179,7 +181,8 @@ bool Integrator::modified(const Integrator& integrator) volume_homogeneous_sampling == integrator.volume_homogeneous_sampling && volume_max_steps == integrator.volume_max_steps && volume_step_size == integrator.volume_step_size && - no_caustics == integrator.no_caustics && + caustics_reflective == integrator.caustics_reflective && + caustics_refractive == integrator.caustics_refractive && filter_glossy == integrator.filter_glossy && layer_flag == integrator.layer_flag && seed == integrator.seed && diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index 380c1a65722..13c10e8ca94 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -43,7 +43,8 @@ public: int volume_max_steps; float volume_step_size; - bool no_caustics; + bool caustics_reflective; + bool caustics_refractive; float filter_glossy; int seed;