[Bf-blender-cvs] [5ff8221] cycles_disney_bsdf_transmittance: Implemented the thin surface diffuse part.

Pascal Schoen noreply at git.blender.org
Wed Dec 14 15:06:49 CET 2016


Commit: 5ff822140fc90fa85c453072dbc1f860d6e252ca
Author: Pascal Schoen
Date:   Mon Nov 14 16:58:09 2016 +0100
Branches: cycles_disney_bsdf_transmittance
https://developer.blender.org/rB5ff822140fc90fa85c453072dbc1f860d6e252ca

Implemented the thin surface diffuse part.

===================================================================

M	intern/cycles/blender/blender_shader.cpp
M	intern/cycles/kernel/closure/bsdf.h
M	intern/cycles/kernel/closure/bsdf_disney_diffuse.h
M	intern/cycles/kernel/closure/bssrdf.h
M	intern/cycles/kernel/kernel_subsurface.h
M	intern/cycles/kernel/osl/osl_bssrdf.cpp
M	intern/cycles/kernel/osl/osl_closures.cpp
M	intern/cycles/kernel/shaders/node_disney_bsdf.osl
M	intern/cycles/kernel/shaders/stdosl.h
M	intern/cycles/kernel/svm/svm_closure.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	source/blender/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c

===================================================================

diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index cb50b74..6f6a4d0 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -528,6 +528,14 @@ static ShaderNode *add_node(Scene *scene,
 				disney->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
 				break;
 		}
+		switch (b_disney_node.surface_type()) {
+			case BL::ShaderNodeBsdfDisney::surface_type_THIN_SURFACE:
+				disney->surface_type = THIN_SURFACE;
+				break;
+			case BL::ShaderNodeBsdfDisney::surface_type_SOLID_SURFACE:
+				disney->surface_type = SOLID_SURFACE;
+				break;
+		}
 		node = disney;
 	}
 	else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index b7c53df..83e33c1 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -133,10 +133,15 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
 				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
 			break;
 		case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+		case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
 		case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
 			label = bsdf_disney_diffuse_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
 				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
 			break;
+		case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+			label = bsdf_disney_retro_reflection_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+			break;
 		case CLOSURE_BSDF_DISNEY_SHEEN_ID:
 			label = bsdf_disney_sheen_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
 				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
@@ -234,9 +239,13 @@ float3 bsdf_eval(KernelGlobals *kg,
 				eval = bsdf_hair_transmission_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
 				break;
 			case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+			case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
 			case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
 				eval = bsdf_disney_diffuse_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
 				break;
+			case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+				eval = bsdf_disney_retro_reflection_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+				break;
 			case CLOSURE_BSDF_DISNEY_SHEEN_ID:
 				eval = bsdf_disney_sheen_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
 				break;
@@ -309,9 +318,13 @@ float3 bsdf_eval(KernelGlobals *kg,
 				eval = bsdf_hair_transmission_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
 				break;
 			case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+			case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
 			case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
 				eval = bsdf_disney_diffuse_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
 				break;
+			case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+				eval = bsdf_disney_retro_reflection_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+				break;
 			case CLOSURE_BSDF_DISNEY_SHEEN_ID:
 				eval = bsdf_disney_sheen_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
 				break;
diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
index ccb5966..a76be38 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
@@ -27,51 +27,174 @@ CCL_NAMESPACE_BEGIN
 typedef ccl_addr_space struct DisneyDiffuseBsdf {
 	SHADER_CLOSURE_BASE;
 
-	float roughness;
+	float roughness, flatness;
 	float3 N;
 } DisneyDiffuseBsdf;
 
+
+/* DIFFUSE */
+
 ccl_device float3 calculate_disney_diffuse_brdf(const DisneyDiffuseBsdf *bsdf,
-	float3 N, float3 V, float3 L, float3 H, float *pdf)
+	float NdotL, float NdotV, float LdotH)
+{
+	float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
+	float Fd = (1.0f - 0.5f * FL) * (1.0f - 0.5f * FV);
+
+	float ss = 0.0f;
+	if(bsdf->flatness > 0.0f) {
+		// Based on Hanrahan-Krueger BRDF approximation of isotropic BSSRDF
+		// 1.25 scale is used to (roughly) preserve albedo
+		// Fss90 used to "flatten" retro-reflection based on roughness
+		float Fss90 = LdotH*LdotH * bsdf->roughness;
+		float Fss = (1.0f + (Fss90 - 1.0f) * FL) * (1.0f + (Fss90 - 1.0f) * FV);
+		ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f);
+	}
+
+	float value = Fd + (ss - Fd) * bsdf->flatness;
+	value *= M_1_PI_F * NdotL;
+
+	return make_float3(value, value, value);
+}
+
+ccl_device int bsdf_disney_diffuse_setup(DisneyDiffuseBsdf *bsdf)
+{
+	bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID;
+	return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device int bsdf_disney_diffuse_transmit_setup(DisneyDiffuseBsdf *bsdf)
+{
+	bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+	return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
+	const float3 omega_in, float *pdf)
+{
+	const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+	bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+
+	if(m_transmittance)
+		return make_float3(0.0f, 0.0f, 0.0f);
+
+	float3 N = bsdf->N;
+
+	if(dot(N, omega_in) > 0.0f) {
+		float3 H = normalize(I + omega_in);
+
+		*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
+		return calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
+	}
+	else {
+		*pdf = 0.0f;
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
+}
+
+ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
+	const float3 omega_in, float *pdf)
 {
-	float NdotL = max(dot(N, L), 0.0f);
-	float NdotV = max(dot(N, V), 0.0f);
+	const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+	bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
 
-	if(NdotL < 0 || NdotV < 0) {
+	if(!m_transmittance)
+		return make_float3(0.0f, 0.0f, 0.0f);
+
+	float3 N = bsdf->N;
+
+	if(dot(-N, omega_in) > 0.0f) {
+		float3 H = normalize(I + omega_in);
+
+		*pdf = fmaxf(dot(-N, omega_in), 0.0f) * M_1_PI_F;
+		return calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(-N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
+	}
+	else {
 		*pdf = 0.0f;
 		return make_float3(0.0f, 0.0f, 0.0f);
 	}
+}
+
+ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
+	float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
+	float3 *eval, float3 *omega_in, float3 *domega_in_dx,
+	float3 *domega_in_dy, float *pdf)
+{
+	const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+	bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+
+	float3 N = bsdf->N;
+
+	if(m_transmittance) {
+		sample_uniform_hemisphere(-N, randu, randv, omega_in, pdf);
+	}
+	else {
+		sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+	}
+
+	if(m_transmittance && dot(-Ng, *omega_in) > 0) {
+		float3 I_t = -((2 * dot(N, I)) * N - I);
+		float3 H = normalize(I_t + *omega_in);
+
+		*eval = calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(-N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
+
+#ifdef __RAY_DIFFERENTIALS__
+		// TODO: find a better approximation for the diffuse bounce
+		*domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+		*domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+#endif
+	}
+	else if(!m_transmittance && dot(Ng, *omega_in) > 0) {
+		float3 H = normalize(I + *omega_in);
+
+		*eval = calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
+
+#ifdef __RAY_DIFFERENTIALS__
+		// TODO: find a better approximation for the diffuse bounce
+		*domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+		*domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+#endif
+	}
+	else {
+		*pdf = 0.0f;
+	}
 
-	float LdotH = dot(L, H);
+	return (m_transmittance) ? LABEL_TRANSMIT|LABEL_DIFFUSE : LABEL_REFLECT|LABEL_DIFFUSE;
+}
+
+
+/* RETRO-REFLECTION */
 
+ccl_device float3 calculate_retro_reflection(const DisneyDiffuseBsdf *bsdf,
+	float NdotL, float NdotV, float LdotH)
+{
 	float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
-	const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * bsdf->roughness;
-	float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV);
+	float RR = 2.0f * bsdf->roughness * LdotH*LdotH;
+
+	float FRR = RR * (FL + FV + FL * FV * (RR - 1.0f));
 
-	float value = M_1_PI_F * NdotL * Fd;
+	float value = M_1_PI_F * FRR * NdotL;
 
 	return make_float3(value, value, value);
 }
 
-ccl_device int bsdf_disney_diffuse_setup(DisneyDiffuseBsdf *bsdf)
+ccl_device int bsdf_disney_retro_reflection_setup(DisneyDiffuseBsdf *bsdf)
 {
-	bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID;
+	bsdf->type = CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID;
 	return SD_BSDF|SD_BSDF_HAS_EVAL;
 }
 
-ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
+ccl_device float3 bsdf_disney_retro_reflection_eval_reflect(const ShaderClosure *sc, const float3 I,
 	const float3 omega_in, float *pdf)
 {
 	const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
 
 	float3 N = bsdf->N;
-	float3 V = I; // outgoing
-	float3 L = omega_in; // incoming
-	float3 H = normalize(L + V);
 
 	if(dot(N, omega_in) > 0.0f) {
+		float3 H = normalize(I + omega_in);
+
 		*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
-		return calculate_disney_diffuse_brdf(bsdf, N, V, L, H, pdf);
+		return calculate_retro_reflection(bsdf, fmaxf(dot(N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
 	}
 	else {
 		*pdf = 0.0f;
@@ -79,13 +202,13 @@ ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, cons
 	}
 }
 
-ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
+ccl_device float3 bsdf_disney_retro_reflection_eval_transmit(const ShaderClosure *sc, const float3 I,
 	const float3 omega_in, float *pdf)
 {
 	return make_float3(0.0f, 0.0f, 0.0f);
 }
 
-ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
+ccl_device int bsdf_disney_retro_reflection_sample(const ShaderClos

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list