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");
/* 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");

View File

@ -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, "

View File

@ -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()

View File

@ -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

View File

@ -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");

View File

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

View File

@ -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),

View File

@ -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 */

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_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);

View File

@ -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 &&

View File

@ -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;