[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59783] trunk/blender: Cycles: add a sharpness input to the Cubic SSS falloff.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Sep 4 00:39:17 CEST 2013


Revision: 59783
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59783
Author:   blendix
Date:     2013-09-03 22:39:17 +0000 (Tue, 03 Sep 2013)
Log Message:
-----------
Cycles: add a sharpness input to the Cubic SSS falloff. When set to 1 this will
give a result more similar to the Compatible falloff option. The scale is x2
though to keep the perceived scatter radius roughly the same while changing the
sharpness. Difference with compatible will be mainly on non-flat geometry.

Modified Paths:
--------------
    trunk/blender/intern/cycles/kernel/closure/bssrdf.h
    trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.cpp
    trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.h
    trunk/blender/intern/cycles/kernel/osl/osl_closures.cpp
    trunk/blender/intern/cycles/kernel/osl/osl_closures.h
    trunk/blender/intern/cycles/kernel/osl/osl_shader.cpp
    trunk/blender/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
    trunk/blender/intern/cycles/kernel/shaders/stdosl.h
    trunk/blender/intern/cycles/kernel/svm/svm_closure.h
    trunk/blender/intern/cycles/render/nodes.cpp
    trunk/blender/intern/cycles/render/nodes.h
    trunk/blender/source/blender/gpu/shaders/gpu_shader_material.glsl
    trunk/blender/source/blender/makesrna/intern/rna_nodetree.c
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c

Modified: trunk/blender/intern/cycles/kernel/closure/bssrdf.h
===================================================================
--- trunk/blender/intern/cycles/kernel/closure/bssrdf.h	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/closure/bssrdf.h	2013-09-03 22:39:17 UTC (rev 59783)
@@ -31,6 +31,7 @@
 	}
 	else {
 		sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* texture blur */
+		sc->T.x = clamp(sc->T.x, 0.0f, 1.0f); /* sharpness */
 		sc->type = type;
 
 		return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF;
@@ -95,17 +96,49 @@
 
 __device float bssrdf_cubic_eval(ShaderClosure *sc, float r)
 {
-	const float Rm = sc->data0;
+	const float sharpness = sc->T.x;
 
-	if(r >= Rm)
-		return 0.0f;
-	
-	/* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
-	const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm;
-	const float f = Rm - min(r, Rm);
-	const float f3 = f*f*f;
+	if(sharpness == 0.0f) {
+		const float Rm = sc->data0;
 
-	return (f3 * 10.0f) / (Rm5 * M_PI_F);
+		if(r >= Rm)
+			return 0.0f;
+
+		/* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
+		const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm;
+		const float f = Rm - r;
+		const float num = f*f*f;
+
+		return (10.0f * num) / (Rm5 * M_PI_F);
+
+	}
+	else {
+		float Rm = sc->data0*(1.0f + sharpness);
+
+		if(r >= Rm)
+			return 0.0f;
+
+		/* custom variation with extra sharpness, to match the previous code */
+		const float y = 1.0f/(1.0f + sharpness);
+		float Rmy, ry, ryinv;
+
+		if(sharpness == 1.0f) {
+			Rmy = sqrtf(Rm);
+			ry = sqrtf(r);
+			ryinv = (ry > 0.0f)? 1.0f/ry: 0.0f;
+		}
+		else {
+			Rmy = powf(Rm, y);
+			ry = powf(r, y);
+			ryinv = (r > 0.0f)? powf(r, 2.0f*y - 2.0f): 0.0f;
+		}
+
+		const float Rmy5 = (Rmy*Rmy) * (Rmy*Rmy) * Rmy;
+		const float f = Rmy - ry;
+		const float num = f*(f*f)*(y*ryinv);
+
+		return (10.0f * num) / (Rmy5 * M_PI_F);
+	}
 }
 
 __device float bssrdf_cubic_pdf(ShaderClosure *sc, float r)
@@ -143,9 +176,16 @@
 
 __device void bssrdf_cubic_sample(ShaderClosure *sc, float xi, float *r, float *h)
 {
-	const float Rm = sc->data0;
-	const float r_ = bssrdf_cubic_quintic_root_find(xi) * Rm;
+	float Rm = sc->data0;
+	float r_ = bssrdf_cubic_quintic_root_find(xi);
 
+	const float sharpness = sc->T.x;
+	if(sharpness != 0.0f) {
+		r_ = powf(r_, 1.0f + sharpness);
+		Rm *= (1.0f + sharpness);
+	}
+	
+	r_ *= Rm;
 	*r = r_;
 
 	/* h^2 + r^2 = Rm^2 */

Modified: trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.cpp
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.cpp	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.cpp	2013-09-03 22:39:17 UTC (rev 59783)
@@ -56,10 +56,8 @@
 
 	void setup()
 	{
-		sc.type = CLOSURE_BSSRDF_COMPATIBLE_ID;
-		sc.prim = NULL;
+		sc.type = CLOSURE_BSSRDF_CUBIC_ID;
 		sc.data0 = fabsf(average(radius));
-		sc.data1 = 0.0f; // XXX texture blur
 	}
 
 	bool mergeable(const ClosurePrimitive *other) const
@@ -85,6 +83,19 @@
 	return params;
 }
 
+ClosureParam *closure_bssrdf_cubic_extended_params()
+{
+	static ClosureParam params[] = {
+		CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, sc.N),
+		CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius),
+		CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1),
+		CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x),
+	    CLOSURE_STRING_KEYPARAM("label"),
+	    CLOSURE_FINISH_PARAM(CubicBSSRDFClosure)
+	};
+	return params;
+}
+
 CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, CubicBSSRDFClosure)
 
 /* Gaussian */
@@ -97,9 +108,7 @@
 	void setup()
 	{
 		sc.type = CLOSURE_BSSRDF_GAUSSIAN_ID;
-		sc.prim = NULL;
 		sc.data0 = fabsf(average(radius));
-		sc.data1 = 0.0f; // XXX texture blurring!
 	}
 
 	bool mergeable(const ClosurePrimitive *other) const
@@ -125,6 +134,18 @@
 	return params;
 }
 
+ClosureParam *closure_bssrdf_gaussian_extended_params()
+{
+	static ClosureParam params[] = {
+		CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N),
+		CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius),
+		CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1),
+	    CLOSURE_STRING_KEYPARAM("label"),
+	    CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure)
+	};
+	return params;
+}
+
 CLOSURE_PREPARE(closure_bssrdf_gaussian_prepare, GaussianBSSRDFClosure)
 
 CCL_NAMESPACE_END

Modified: trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.h
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.h	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/osl/osl_bssrdf.h	2013-09-03 22:39:17 UTC (rev 59783)
@@ -48,7 +48,7 @@
 	ShaderClosure sc;
 	float3 radius;
 
-	CBSSRDFClosure() : OSL::ClosurePrimitive(BSSRDF) { }
+	CBSSRDFClosure() : OSL::ClosurePrimitive(BSSRDF) { memset(&sc, 0, sizeof(sc)); }
 	~CBSSRDFClosure() { }
 
 	int scattering() const { return LABEL_DIFFUSE; }

Modified: trunk/blender/intern/cycles/kernel/osl/osl_closures.cpp
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_closures.cpp	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/osl/osl_closures.cpp	2013-09-03 22:39:17 UTC (rev 59783)
@@ -221,6 +221,10 @@
 		closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare);
 	register_closure(ss, "bssrdf_gaussian", id++,
 		closure_bssrdf_gaussian_params(), closure_bssrdf_gaussian_prepare);
+	register_closure(ss, "bssrdf_cubic", id++,
+		closure_bssrdf_cubic_extended_params(), closure_bssrdf_cubic_prepare);
+	register_closure(ss, "bssrdf_gaussian", id++,
+		closure_bssrdf_gaussian_extended_params(), closure_bssrdf_gaussian_prepare);
 }
 
 CCL_NAMESPACE_END

Modified: trunk/blender/intern/cycles/kernel/osl/osl_closures.h
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_closures.h	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/osl/osl_closures.h	2013-09-03 22:39:17 UTC (rev 59783)
@@ -52,6 +52,8 @@
 OSL::ClosureParam *closure_westin_sheen_params();
 OSL::ClosureParam *closure_bssrdf_cubic_params();
 OSL::ClosureParam *closure_bssrdf_gaussian_params();
+OSL::ClosureParam *closure_bssrdf_cubic_extended_params();
+OSL::ClosureParam *closure_bssrdf_gaussian_extended_params();
 
 void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
 void closure_background_prepare(OSL::RendererServices *, int id, void *data);

Modified: trunk/blender/intern/cycles/kernel/osl/osl_shader.cpp
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_shader.cpp	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/osl/osl_shader.cpp	2013-09-03 22:39:17 UTC (rev 59783)
@@ -239,6 +239,7 @@
 						sc.type = bssrdf->sc.type;
 						sc.N = bssrdf->sc.N;
 						sc.data1 = bssrdf->sc.data1;
+						sc.T.x = bssrdf->sc.T.x;
 						sc.prim = NULL;
 
 						/* disable in case of diffuse ancestor, can't see it well then and

Modified: trunk/blender/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
===================================================================
--- trunk/blender/intern/cycles/kernel/shaders/node_subsurface_scattering.osl	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/shaders/node_subsurface_scattering.osl	2013-09-03 22:39:17 UTC (rev 59783)
@@ -20,14 +20,15 @@
 	color Color = 0.8,
 	float Scale = 1.0,
 	vector Radius = vector(0.1, 0.1, 0.1),
-	float TextureBlur = 0.0, // XXX use
+	float TextureBlur = 0.0,
+	float Sharpness = 0.0,
 	string Falloff = "Cubic",
 	normal Normal = N,
 	output closure color BSSRDF = 0)
 {
 	if(Falloff == "Gaussian")
-		BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius);
-	else /* Cubic, hardcoded to compatible closure for now */
-		BSSRDF = Color * bssrdf_cubic(N, Scale * Radius);
+		BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius, TextureBlur);
+	else
+		BSSRDF = Color * bssrdf_cubic(N, Scale * Radius, TextureBlur, Sharpness);
 }
 

Modified: trunk/blender/intern/cycles/kernel/shaders/stdosl.h
===================================================================
--- trunk/blender/intern/cycles/kernel/shaders/stdosl.h	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/shaders/stdosl.h	2013-09-03 22:39:17 UTC (rev 59783)
@@ -465,11 +465,12 @@
 closure color ambient_occlusion() BUILTIN;
 
 // BSSRDF
+closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN;
+closure color bssrdf_gaussian(normal N, vector radius, float texture_blur) BUILTIN;
+
+// Backwards compatibility
 closure color bssrdf_cubic(normal N, vector radius) BUILTIN;
 closure color bssrdf_gaussian(normal N, vector radius) BUILTIN;
-
-// Backwards compatibility
-
 closure color specular_toon(normal N, float size, float smooth) BUILTIN;
 
 // Renderer state

Modified: trunk/blender/intern/cycles/kernel/svm/svm_closure.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_closure.h	2013-09-03 22:32:03 UTC (rev 59782)
+++ trunk/blender/intern/cycles/kernel/svm/svm_closure.h	2013-09-03 22:39:17 UTC (rev 59783)
@@ -108,13 +108,13 @@
 	if(mix_weight == 0.0f)
 		return;
 
-	float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; 
+	float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N; 
 #else
 	decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
 	float mix_weight = 1.0f;
 
 	uint4 data_node = read_node(kg, offset);
-	float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; 
+	float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N; 
 #endif
 
 	float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
@@ -279,10 +279,10 @@
 				sc->N = N;
 
 #ifdef __ANISOTROPIC__
-				sc->T = stack_load_float3(stack, data_node.z);
+				sc->T = stack_load_float3(stack, data_node.y);
 
 				/* rotate tangent */
-				float rotation = stack_load_float(stack, data_node.w);
+				float rotation = stack_load_float(stack, data_node.z);
 
 				if(rotation != 0.0f)
 					sc->T = rotate_around_axis(sc->T, sc->N, rotation * M_2PI_F);
@@ -353,7 +353,9 @@
 
 			if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) {
 				/* radius * scale */
-				float3 radius = stack_load_float3(stack, data_node.w)*param1;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list