[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52587] trunk/blender/intern/cycles: Fix #32907: failure rendering a complex node setup, hitting fixed max number
Brecht Van Lommel
brechtvanlommel at pandora.be
Mon Nov 26 22:59:43 CET 2012
Revision: 52587
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52587
Author: blendix
Date: 2012-11-26 21:59:41 +0000 (Mon, 26 Nov 2012)
Log Message:
-----------
Fix #32907: failure rendering a complex node setup, hitting fixed max number
of closures limit. Optimized the code now so it can handle more.
Change SVM mix/add closure handling, now we transform the node graph so that
the mix weights are fed into the closure nodes directly.
Modified Paths:
--------------
trunk/blender/intern/cycles/kernel/svm/svm_closure.h
trunk/blender/intern/cycles/render/graph.cpp
trunk/blender/intern/cycles/render/graph.h
trunk/blender/intern/cycles/render/nodes.cpp
trunk/blender/intern/cycles/render/nodes.h
trunk/blender/intern/cycles/render/svm.cpp
trunk/blender/intern/cycles/render/svm.h
Modified: trunk/blender/intern/cycles/kernel/svm/svm_closure.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_closure.h 2012-11-26 21:28:24 UTC (rev 52586)
+++ trunk/blender/intern/cycles/kernel/svm/svm_closure.h 2012-11-26 21:59:41 UTC (rev 52587)
@@ -64,11 +64,22 @@
#endif
}
-__device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mix_weight)
+__device_inline ShaderClosure *svm_node_closure_get_weight(ShaderData *sd, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
+ ShaderClosure *sc = &sd->closure[sd->num_closure];
+
sc->weight *= mix_weight;
sc->sample_weight = fabsf(average(sc->weight));
+
+ if(sc->sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
+ sd->num_closure++;
+ return sc;
+ }
+
+ return NULL;
+#else
+ return &sd->closure;
#endif
}
@@ -101,33 +112,39 @@
switch(type) {
case CLOSURE_BSDF_DIFFUSE_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- float roughness = param1;
+ if(sc) {
+ sc->N = N;
- if(roughness == 0.0f) {
- sd->flag |= bsdf_diffuse_setup(sc);
+ float roughness = param1;
+
+ if(roughness == 0.0f) {
+ sd->flag |= bsdf_diffuse_setup(sc);
+ }
+ else {
+ sc->data0 = roughness;
+ sd->flag |= bsdf_oren_nayar_setup(sc);
+ }
}
- else {
- sc->data0 = roughness;
- sd->flag |= bsdf_oren_nayar_setup(sc);
- }
break;
}
case CLOSURE_BSDF_TRANSLUCENT_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
- sd->flag |= bsdf_translucent_setup(sc);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
+ sd->flag |= bsdf_translucent_setup(sc);
+ }
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
- sd->flag |= bsdf_transparent_setup(sc);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
+ sd->flag |= bsdf_transparent_setup(sc);
+ }
break;
}
case CLOSURE_BSDF_REFLECTION_ID:
@@ -137,19 +154,21 @@
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- sc->data0 = param1;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFLECTION_ID)
- sd->flag |= bsdf_reflection_setup(sc);
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
- sd->flag |= bsdf_microfacet_beckmann_setup(sc);
- else
- sd->flag |= bsdf_microfacet_ggx_setup(sc);
+ if(sc) {
+ sc->N = N;
+ sc->data0 = param1;
+ /* setup bsdf */
+ if(type == CLOSURE_BSDF_REFLECTION_ID)
+ sd->flag |= bsdf_reflection_setup(sc);
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
+ sd->flag |= bsdf_microfacet_beckmann_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_setup(sc);
+ }
+
break;
}
case CLOSURE_BSDF_REFRACTION_ID:
@@ -159,22 +178,24 @@
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- sc->data0 = param1;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- float eta = fmaxf(param2, 1.0f + 1e-5f);
- sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
+ if(sc) {
+ sc->N = N;
+ sc->data0 = param1;
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFRACTION_ID)
- sd->flag |= bsdf_refraction_setup(sc);
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
- sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
- else
- sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+ float eta = fmaxf(param2, 1.0f + 1e-5f);
+ sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
+ /* setup bsdf */
+ if(type == CLOSURE_BSDF_REFRACTION_ID)
+ sd->flag |= bsdf_refraction_setup(sc);
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+ }
+
break;
}
case CLOSURE_BSDF_SHARP_GLASS_ID:
@@ -195,32 +216,36 @@
#ifdef __MULTI_CLOSURE__
/* reflection */
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
-
+ ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight;
float sample_weight = sc->sample_weight;
- svm_node_closure_set_mix_weight(sc, mix_weight*fresnel);
- svm_node_glass_setup(sd, sc, type, eta, roughness, false);
+ sc = svm_node_closure_get_weight(sd, mix_weight*fresnel);
+ if(sc) {
+ sc->N = N;
+ svm_node_glass_setup(sd, sc, type, eta, roughness, false);
+ }
+
/* refraction */
- sc = svm_node_closure_get(sd);
- sc->N = N;
-
+ sc = &sd->closure[sd->num_closure];
sc->weight = weight;
sc->sample_weight = sample_weight;
- svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel));
- svm_node_glass_setup(sd, sc, type, eta, roughness, true);
+ sc = svm_node_closure_get_weight(sd, mix_weight*(1.0f - fresnel));
+
+ if(sc) {
+ sc->N = N;
+ svm_node_glass_setup(sd, sc, type, eta, roughness, true);
+ }
#else
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- bool refract = (randb > fresnel);
-
- svm_node_closure_set_mix_weight(sc, mix_weight);
- svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
+ if(sc) {
+ sc->N = N;
+ bool refract = (randb > fresnel);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
+ }
#endif
break;
@@ -230,46 +255,50 @@
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
+ if(sc) {
+ sc->N = N;
+
#ifdef __ANISOTROPIC__
- sc->T = stack_load_float3(stack, data_node.z);
+ sc->T = stack_load_float3(stack, data_node.z);
- /* rotate tangent */
- float rotation = stack_load_float(stack, data_node.w);
+ /* rotate tangent */
+ float rotation = stack_load_float(stack, data_node.w);
- if(rotation != 0.0f)
- sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
+ if(rotation != 0.0f)
+ sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
- /* compute roughness */
- float roughness = param1;
- float anisotropy = clamp(param2, -0.99f, 0.99f);
+ /* compute roughness */
+ float roughness = param1;
+ float anisotropy = clamp(param2, -0.99f, 0.99f);
- if(anisotropy < 0.0f) {
- sc->data0 = roughness/(1.0f + anisotropy);
- sc->data1 = roughness*(1.0f + anisotropy);
- }
- else {
- sc->data0 = roughness*(1.0f - anisotropy);
- sc->data1 = roughness/(1.0f - anisotropy);
- }
+ if(anisotropy < 0.0f) {
+ sc->data0 = roughness/(1.0f + anisotropy);
+ sc->data1 = roughness*(1.0f + anisotropy);
+ }
+ else {
+ sc->data0 = roughness*(1.0f - anisotropy);
+ sc->data1 = roughness/(1.0f - anisotropy);
+ }
- sd->flag |= bsdf_ward_setup(sc);
+ sd->flag |= bsdf_ward_setup(sc);
#else
- sd->flag |= bsdf_diffuse_setup(sc);
+ sd->flag |= bsdf_diffuse_setup(sc);
#endif
+ }
break;
}
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- /* sigma */
- sc->data0 = clamp(param1, 0.0f, 1.0f);
- sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
+ if(sc) {
+ sc->N = N;
+
+ /* sigma */
+ sc->data0 = clamp(param1, 0.0f, 1.0f);
+ sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
+ }
break;
}
default:
@@ -298,19 +327,21 @@
switch(type) {
case CLOSURE_VOLUME_TRANSPARENT_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- float density = param1;
- sd->flag |= volume_transparent_setup(sc, density);
+ if(sc) {
+ float density = param1;
+ sd->flag |= volume_transparent_setup(sc, density);
+ }
break;
}
case CLOSURE_VOLUME_ISOTROPIC_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight);
- float density = param1;
- sd->flag |= volume_isotropic_setup(sc, density);
+ if(sc) {
+ float density = param1;
+ sd->flag |= volume_isotropic_setup(sc, density);
+ }
break;
}
default:
Modified: trunk/blender/intern/cycles/render/graph.cpp
===================================================================
--- trunk/blender/intern/cycles/render/graph.cpp 2012-11-26 21:28:24 UTC (rev 52586)
+++ trunk/blender/intern/cycles/render/graph.cpp 2012-11-26 21:59:41 UTC (rev 52587)
@@ -37,7 +37,7 @@
value = make_float3(0, 0, 0);
stack_offset = SVM_STACK_INVALID;
default_value = NONE;
- osl_only = false;
+ usage = USE_ALL;
}
ShaderOutput::ShaderOutput(ShaderNode *parent_, const char *name_, ShaderSocketType type_)
@@ -85,27 +85,29 @@
return NULL;
}
-ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value)
+ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value, int usage)
{
ShaderInput *input = new ShaderInput(this, name, type);
input->value.x = value;
+ input->usage = usage;
inputs.push_back(input);
return input;
}
-ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value)
+ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value, int usage)
{
ShaderInput *input = new ShaderInput(this, name, type);
input->value = value;
+ input->usage = usage;
inputs.push_back(input);
return input;
}
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list