Cycles: Split caustics option, to allow separate control for Reflection and Refraction caustics.

This way artists can only disable/enable refraction or reflection caustics.
See Cycles logs for an example: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72/Cycles

Differential revision: https://developer.blender.org/D766
This commit is contained in:
Thomas Dinges
2014-09-05 20:39:35 +02:00
parent cdd1d5a93c
commit 8243c55f14
11 changed files with 71 additions and 30 deletions

View File

@@ -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"); xml_read_int(&integrator->volume_max_steps, node, "volume_max_steps");
/* Various Settings */ /* 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_float(&integrator->filter_glossy, node, "filter_glossy");
xml_read_int(&integrator->seed, node, "seed"); xml_read_int(&integrator->seed, node, "seed");

View File

@@ -259,11 +259,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=True, default=True,
) )
cls.no_caustics = BoolProperty( cls.caustics_reflective = BoolProperty(
name="No Caustics", name="Reflective Caustics",
description="Leave out caustics, resulting in a darker image with less noise", description="Leave out reflective caustics, resulting in a darker image with less noise",
default=False, 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( cls.blur_glossy = FloatProperty(
name="Filter Glossy", name="Filter Glossy",
description="Adaptively blur glossy shaders after blurry bounces, " description="Adaptively blur glossy shaders after blurry bounces, "

View File

@@ -210,7 +210,8 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel):
col.separator() col.separator()
col.prop(cscene, "no_caustics") col.prop(cscene, "caustics_reflective")
col.prop(cscene, "caustics_refractive")
col.prop(cscene, "blur_glossy") col.prop(cscene, "blur_glossy")
col = split.column() col = split.column()

View File

@@ -33,3 +33,15 @@ def do_versions(self):
cscene = scene.cycles cscene = scene.cycles
if not cscene.is_property_set("volume_bounces"): if not cscene.is_property_set("volume_bounces"):
cscene.volume_bounces = 1 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

View File

@@ -180,7 +180,8 @@ void BlenderSync::sync_integrator()
integrator->volume_max_steps = get_int(cscene, "volume_max_steps"); integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
integrator->volume_step_size = get_float(cscene, "volume_step_size"); 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->filter_glossy = get_float(cscene, "blur_glossy");
integrator->seed = get_int(cscene, "seed"); integrator->seed = get_int(cscene, "seed");

View File

@@ -874,7 +874,8 @@ typedef struct KernelIntegrator {
int transparent_shadows; int transparent_shadows;
/* caustics */ /* caustics */
int no_caustics; int caustics_reflective;
int caustics_refractive;
float filter_glossy; float filter_glossy;
/* seed */ /* seed */

View File

@@ -105,7 +105,7 @@ BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LA
CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0), CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) 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.N),
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.T), CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.T),
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data0), 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), CLOSURE_FLOAT_PARAM(GlossyToonClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon) 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_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) 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.N),
CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.T), CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.T),
CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data1), CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso) 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_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) 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.N),
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.T), CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.T),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data1), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso) 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_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data2), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data2),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) 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_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data2), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data2),

View File

@@ -164,12 +164,15 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
CBSDFClosure *bsdf = (CBSDFClosure *)prim; CBSDFClosure *bsdf = (CBSDFClosure *)prim;
int scattering = bsdf->scattering(); int scattering = bsdf->scattering();
/* no caustics option */ /* caustic options */
if(scattering == LABEL_GLOSSY && (path_flag & PATH_RAY_DIFFUSE)) { if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
KernelGlobals *kg = sd->osl_globals; 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; return;
} }
}
/* sample weight */ /* sample weight */
float sample_weight = fabsf(average(weight)); float sample_weight = fabsf(average(weight));

View File

@@ -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_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
#ifdef __CAUSTICS_TRICKS__ #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; break;
#endif #endif
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); 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_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
#ifdef __CAUSTICS_TRICKS__ #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; break;
#endif #endif
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); 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_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
#ifdef __CAUSTICS_TRICKS__ #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; break;
}
#endif #endif
/* index of refraction */ /* index of refraction */
float eta = fmaxf(param2, 1e-5f); float eta = fmaxf(param2, 1e-5f);
@@ -262,11 +264,20 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float sample_weight = sc->sample_weight; float sample_weight = sc->sample_weight;
sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel);
#ifdef __CAUSTICS_TRICKS__
if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
#endif
{
if(sc) { if(sc) {
sc->N = N; sc->N = N;
svm_node_glass_setup(sd, sc, type, eta, roughness, false); 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 */ /* refraction */
sc = &sd->closure[sd->num_closure]; sc = &sd->closure[sd->num_closure];
@@ -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_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: { case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
#ifdef __CAUSTICS_TRICKS__ #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; break;
#endif #endif
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);

View File

@@ -43,7 +43,8 @@ Integrator::Integrator()
volume_max_steps = 1024; volume_max_steps = 1024;
volume_step_size = 0.1f; volume_step_size = 0.1f;
no_caustics = false; caustics_reflective = true;
caustics_refractive = true;
filter_glossy = 0.0f; filter_glossy = 0.0f;
seed = 0; seed = 0;
layer_flag = ~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_max_steps = volume_max_steps;
kintegrator->volume_step_size = volume_step_size; 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->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy;
kintegrator->seed = hash_int(seed); kintegrator->seed = hash_int(seed);
@@ -179,7 +181,8 @@ bool Integrator::modified(const Integrator& integrator)
volume_homogeneous_sampling == integrator.volume_homogeneous_sampling && volume_homogeneous_sampling == integrator.volume_homogeneous_sampling &&
volume_max_steps == integrator.volume_max_steps && volume_max_steps == integrator.volume_max_steps &&
volume_step_size == integrator.volume_step_size && 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 && filter_glossy == integrator.filter_glossy &&
layer_flag == integrator.layer_flag && layer_flag == integrator.layer_flag &&
seed == integrator.seed && seed == integrator.seed &&

View File

@@ -43,7 +43,8 @@ public:
int volume_max_steps; int volume_max_steps;
float volume_step_size; float volume_step_size;
bool no_caustics; bool caustics_reflective;
bool caustics_refractive;
float filter_glossy; float filter_glossy;
int seed; int seed;