[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