[Bf-blender-cvs] [3ed1e08] cycles_disney_bsdf_transmittance: Implemented the specular transmission part of the thin surface approximation.

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


Commit: 3ed1e08f66feffbf554656d3882e77321e8a0b09
Author: Pascal Schoen
Date:   Tue Nov 15 10:53:30 2016 +0100
Branches: cycles_disney_bsdf_transmittance
https://developer.blender.org/rB3ed1e08f66feffbf554656d3882e77321e8a0b09

Implemented the specular transmission part of the thin surface
approximation.

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

M	intern/cycles/kernel/shaders/node_disney_bsdf.osl
M	intern/cycles/kernel/svm/svm_closure.h

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

diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
index 9b1bd72..8b5bacb 100644
--- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
@@ -108,20 +108,23 @@ shader node_disney_bsdf(
 
 	if (transp > 1e-5) {
 		color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
-		float eta = backfacing() ? 1.0 / f : f;
+		float eta = (backfacing() && (surface_type == "Solid Surface")) ? 1.0 / f : f;
 
-		if (distribution == "GGX" || Roughness <= 5e-2) {
+		if (distribution == "GGX" || Roughness <= 5e-2 || surface_type == "Thin Surface") {
 			float cosNO = dot(Normal, I);
 			float Fr = fresnel_dielectric_cos(cosNO, eta);
 
-		float refl_roughness = Roughness;
-		if (Roughness <= 1e-2)
-			refl_roughness = 0.0;
+			float refl_roughness = Roughness;
+			if (Roughness <= 1e-2)
+				refl_roughness = 0.0;
 
 			float refraction_roughness = refl_roughness;
 			if (distribution == "GGX")
 				refraction_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - RefractionRoughness);
 
+			if (surface_type == "Thin Surface")
+				refraction_roughness = refraction_roughness * (0.65 * eta - 0.35);
+
 			BSDF = BSDF + transp * (Fr * microfacet_ggx_fresnel(Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
 			       (1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, refraction_roughness * refraction_roughness, eta));
 		} else {
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index d4b6b90..6e75aee 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -115,7 +115,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 				T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
 
 			/* calculate ior */
-			float ior = (ccl_fetch(sd, flag) & SD_BACKFACING) ? 1.0f / eta : eta;
+			float ior = ((ccl_fetch(sd, flag) & SD_BACKFACING) && (surface_type == SOLID_SURFACE)) ? 1.0f / eta : eta;
 
 			// calculate fresnel for refraction
 			float cosNO = dot(N, ccl_fetch(sd, I));
@@ -369,7 +369,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 					float3 glass_weight = weight * spec_transp;
 					float3 cspec0 = base_color * specular_tint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
 
-					if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
+					if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || surface_type == THIN_SURFACE) { /* use single-scatter GGX */
 						float refl_roughness = roughness;
 
 						/* reflection */
@@ -431,6 +431,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 								else
 									refraction_roughness = refl_roughness;
 
+								/* Remap the roughness for thin surfaces as introduced in the 2015 Disney paper:
+								 *
+								 * Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering
+								 * Burley, Brent (Walt Disney Animation Studios) */
+								if(surface_type == THIN_SURFACE) {
+									refraction_roughness *= 0.65f * ior - 0.35f;
+								}
+
 								bsdf->alpha_x = refraction_roughness * refraction_roughness;
 								bsdf->alpha_y = refraction_roughness * refraction_roughness;
 								bsdf->ior = ior;




More information about the Bf-blender-cvs mailing list