[Bf-blender-cvs] [cc267e5] cycles_disney_brdf: Implemented the Disney clearcoat as a variation of the microfacet bsdf, removed the transparency roughness again and added an input for anisotropic rotations

Pascal Schoen noreply at git.blender.org
Tue Aug 16 15:23:08 CEST 2016


Commit: cc267e52f20d036a66aeeff127ee1c856f7c651b
Author: Pascal Schoen
Date:   Wed Aug 3 15:00:25 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rBcc267e52f20d036a66aeeff127ee1c856f7c651b

Implemented the Disney clearcoat as a variation of the microfacet bsdf,
removed the transparency roughness again and added an input for
anisotropic rotations

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

M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/shaders/node_disney_bsdf.osl
M	intern/cycles/kernel/svm/svm_closure.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c

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

diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 7173ecd..7ccb29c 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN
 
 typedef ccl_addr_space struct MicrofacetExtra {
 	float3 color, cspec0;
-	bool use_fresnel;
+	bool use_fresnel, is_disney_clearcoat;
 } MicrofacetExtra;
 
 typedef ccl_addr_space struct MicrofacetBsdf {
@@ -247,10 +247,11 @@ ccl_device_inline float3 microfacet_sample_stretched(
  * Anisotropy is only supported for reflection currently, but adding it for
  * transmission is just a matter of copying code from reflection if needed. */
 
-ccl_device int bsdf_microfacet_ggx_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false)
+ccl_device int bsdf_microfacet_ggx_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false, bool is_disney_clearcoat = false)
 {
 	if (bsdf->extra) {
 		bsdf->extra->use_fresnel = use_fresnel;
+		bsdf->extra->is_disney_clearcoat = is_disney_clearcoat;
 
 		bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
 		bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
@@ -284,6 +285,7 @@ ccl_device int bsdf_microfacet_ggx_aniso_setup(MicrofacetBsdf *bsdf, bool use_fr
 {
 	if (bsdf->extra) {
 		bsdf->extra->use_fresnel = use_fresnel;
+		bsdf->extra->is_disney_clearcoat = false;
 
 		bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
 		bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
@@ -302,6 +304,7 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(MicrofacetBsdf *bsdf, bool u
 {
 	if (bsdf->extra) {
 		bsdf->extra->use_fresnel = use_fresnel;
+		bsdf->extra->is_disney_clearcoat = false;
 
 		bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
 		bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
@@ -355,6 +358,10 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
 			D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
 
 			/* eq. 34: now calculate G1(i,m) and G1(o,m) */
+			if (bsdf->extra)
+				if (bsdf->extra->is_disney_clearcoat)
+					alpha2 = 0.0625f;
+
 			G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
 			G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); 
 		}
@@ -550,6 +557,13 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
 							float cosNI = dot(N, *omega_in);
 
 							/* eq. 34: now calculate G1(i,m) */
+							if (bsdf->extra)
+								if (bsdf->extra->is_disney_clearcoat) {
+									// recalculate G1o
+									G1o = 2 / (1 + safe_sqrtf(1 + 0.0625f * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+									alpha2 = 0.0625f;
+								}
+
 							G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); 
 						}
 						else {
diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
index dce39b2..06f1e97 100644
--- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
@@ -32,11 +32,10 @@ shader node_disney_bsdf(
     float ClearcoatGloss = 1.0,
     float IOR = 1.45,
     float Transparency = 0.0,
-    float RefractionRoughness = 0.0,
+    float AnisotropicRotation = 0.0,
 	normal Normal = N,
 	normal ClearcoatNormal = N,
 	normal Tangent = normalize(dPdu),
-    //normal AnisotropicRotation = normal(0, 0, 0),
 	output closure color BSDF = 0)
 {
 	float f = max(IOR, 1e-5);
@@ -47,8 +46,6 @@ shader node_disney_bsdf(
     float transp = clamp(Transparency, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
     float specular_weight = (1.0 - transp);
     
-    float refr_roughness = 1.0 - (1.0 - Roughness) * (1.0 - RefractionRoughness);
-    
     if (diffuse_weight > 0.0) {
         BSDF = (((Subsurface * BaseColor * bssrdf_burley(Normal, vector(1.0, 1.0, 1.0), 0.0, BaseColor)) + disney_diffuse(Normal, BaseColor, Roughness) * (1.0 - Subsurface))
                 + disney_sheen(Normal, BaseColor, Sheen, SheenTint)) * diffuse_weight;
@@ -58,10 +55,10 @@ shader node_disney_bsdf(
         BSDF = BSDF + specular_weight * disney_specular(Normal, Tangent, BaseColor, Metallic, Specular,
                                       SpecularTint, Roughness, Anisotropic)
                     + (1.0 - specular_weight) * (Fr * disney_specular(Normal, Tangent, BaseColor, 0.0, 12.5,
-                                      SpecularTint, Roughness, 0.0) + (1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, refr_roughness * refr_roughness, eta));
+                                      SpecularTint, Roughness, 0.0) + (1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, Roughness * Roughness, eta));
     } else if (transp > 0.0) {
         BSDF = BSDF + transp * (disney_specular(Normal, Tangent, BaseColor, 0.0, 12.5, SpecularTint, Roughness, 0.0)
-                + BaseColor * microfacet_ggx_refraction(Normal, refr_roughness * refr_roughness, eta));
+                + BaseColor * microfacet_ggx_refraction(Normal, Roughness * Roughness, eta));
     }
 
     if (Clearcoat != 0.0) {
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 2f88630..332535b 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -78,14 +78,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 	switch(type) {
 		case CLOSURE_BSDF_DISNEY_ID: {
 			uint specular_offset, roughness_offset, specularTint_offset, anisotropic_offset, sheen_offset,
-				sheenTint_offset, clearcoat_offset, clearcoatGloss_offset, eta_offset, transparency_offset, refr_roughness_offset;
+				sheenTint_offset, clearcoat_offset, clearcoatGloss_offset, eta_offset, transparency_offset, anisotropic_rotation_offset;
 			uint tmp0;
 			uint4 data_node2 = read_node(kg, offset);
 
 			float3 T = stack_load_float3(stack, data_node.y);
 			decode_node_uchar4(data_node.z, &specular_offset, &roughness_offset, &specularTint_offset, &anisotropic_offset);
 			decode_node_uchar4(data_node.w, &sheen_offset, &sheenTint_offset, &clearcoat_offset, &clearcoatGloss_offset);
-			decode_node_uchar4(data_node2.x, &eta_offset, &transparency_offset, &refr_roughness_offset, &tmp0);
+			decode_node_uchar4(data_node2.x, &eta_offset, &transparency_offset, &anisotropic_rotation_offset, &tmp0);
 
 			// get disney parameters
 			float metallic = param1;
@@ -99,10 +99,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 			float clearcoat = stack_load_float(stack, clearcoat_offset);
 			float clearcoatGloss = stack_load_float(stack, clearcoatGloss_offset);
 			float transparency = stack_load_float(stack, transparency_offset);
-			float refr_roughness = stack_load_float(stack, refr_roughness_offset);
-			refr_roughness = 1.0f - (1.0f - roughness) * (1.0f - refr_roughness);
+			float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
 			float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
 
+			/* rotate tangent */
+			if (anisotropic_rotation != 0.0f)
+				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;
 
 			// calculate fresnel for refraction
@@ -283,8 +287,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 						bsdf->extra = extra;
 						bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
 
-						bsdf->alpha_x = refr_roughness * refr_roughness;
-						bsdf->alpha_y = refr_roughness * refr_roughness;
+						bsdf->alpha_x = roughness * roughness;
+						bsdf->alpha_y = roughness * roughness;
 						bsdf->ior = ior;
 
 						bsdf->extra->color = baseColor;
@@ -302,18 +306,24 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 			if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
 #endif
 				if (clearcoat > 0.0f) {
-					float3 clearcoat_weight = weight;
+					float3 clearcoat_weight = 0.25f * clearcoat * weight;
 					float clearcoat_sample_weight = fabsf(average(clearcoat_weight));
 
-					DisneyClearcoatBsdf *bsdf = (DisneyClearcoatBsdf*)bsdf_alloc(sd, sizeof(DisneyClearcoatBsdf), clearcoat_weight);
+					MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), clearcoat_weight);
+					MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
 
-					if (bsdf) {
+					if (bsdf && extra) {
 						bsdf->N = CN;
-						bsdf->clearcoat = clearcoat;
-						bsdf->clearcoatGloss = clearcoatGloss;
+						bsdf->ior = 0.0f;
+						bsdf->extra = extra;
+
+						bsdf->alpha_x = 0.1f * (1.0f - clearcoatGloss) + 0.001f * clearcoatGloss;
+						bsdf->alpha_y = 0.1f * (1.0f - clearcoatGloss) + 0.001f * clearcoatGloss;
+
+						bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
 
 						/* setup bsdf */
-						ccl_fetch(sd, flag) |= bsdf_disney_clearcoat_setup(bsdf);
+						ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(bsdf, true, true);
 					}
 				}
 #ifdef __CAUSTICS_TRICKS__
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index cf36636..c377e89 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2226,7 +2226,7 @@ NODE_DEFINE(DisneyBsdfNode)
 	SOCKET_IN_FLOAT(clearcoatGloss, "ClearcoatGloss", 0.0f);
 	SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
 	SOCKET_IN_FLOAT(transparency, "Transparency", 0.0f);
-	SOCKET_IN_FLOAT(refractionRoughness, "RefractionRoughness", 0.0f);
+	SOCKET_IN_FLOAT(anisotropicRotation, "AnisotropicRotation", 0.0f);
 	SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
 	SOCKET_IN_NORMAL(clearcoatNormal, "ClearcoatNormal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
 	SOCKET_IN_NORMAL(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
@@ -2247,7 +2247,7 @@ DisneyBsdfNode::DisneyBsdfNode()
 void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface,
 	ShaderInput *specular, ShaderI

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list