[Bf-blender-cvs] [dbad91c] cycles_disney_brdf: Added a roughness parameter for refractions (for scattering of the rays within an object)

Pascal Schoen noreply at git.blender.org
Wed Jul 20 11:24:25 CEST 2016


Commit: dbad91ca6d46f5a4a6f2ba7ed4c811ffa723942f
Author: Pascal Schoen
Date:   Wed Jul 20 11:13:00 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rBdbad91ca6d46f5a4a6f2ba7ed4c811ffa723942f

Added a roughness parameter for refractions (for scattering of the rays
within an object)

With this, one can create a translucent material with a smooth surface and
with a milky look.

The final refraction roughness has to be calculated using the surface
roughness and the refraction roughness because those two are correlated
for refractions. If a ray hits a rough surface of a translucent material,
it is scattered while entering the surface. Then it is scattered further
within the object. The calculation I'm using is the following:

RefrRoughnessFinal = 1.0 - (1.0 - Roughness) * (1.0 - RefrRoughness)

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

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/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
index b6312c6..b608b73 100644
--- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
@@ -31,6 +31,7 @@ shader node_disney_bsdf(
     float ClearcoatGloss = 1.0,
     float IOR = 1.45,
     float Transparency = 0.0,
+    float RefractionRoughness = 0.0,
 	normal Normal = N,
 	normal ClearcoatNormal = N,
 	normal Tangent = normalize(dPdu),
@@ -39,23 +40,27 @@ shader node_disney_bsdf(
 {
 	float f = max(IOR, 1e-5);
 	float eta = backfacing() ? 1.0 / f : f;
-	float cosi = dot(I, Normal);
-	float Fr = fresnel_dielectric_cos(cosi, eta);
-    float trans = clamp(Transparency, 0.0, 1.0);
-    float metal = clamp(Metallic, 0.0, 1.0);
-    float specWeight = mix(1.0, Fr, mix(trans, 0.0, metal));
+	float cosNO = dot(Normal, I);
+	float Fr = fresnel_dielectric_cos(cosNO, eta);
+    float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transparency, 0.0, 1.0));
+    float transp = clamp(Transparency, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
+    float specular_weight = (1.0 - transp);
     
-    if (metal < 1.0) {
+    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)) * (1.0 - metal) * (1.0 - trans);
+                + disney_sheen(Normal, BaseColor, Sheen, SheenTint)) * diffuse_weight;
     }
 
     if (Specular != 0.0 || Metallic != 0.0) {
-        BSDF = BSDF + specWeight * disney_specular(Normal, Tangent, BaseColor, Metallic, Specular,
+        BSDF = BSDF + specular_weight * disney_specular(Normal, Tangent, BaseColor, Metallic, Specular,
                                       SpecularTint, Roughness, Anisotropic)
-                    + (1.0 - specWeight) * BaseColor * microfacet_ggx_refraction(Normal, Roughness * Roughness, eta);
-    } else if (trans > 0.0) {
-        BSDF = BSDF + trans * microfacet_ggx_refraction(Normal, Roughness * Roughness, eta);
+                    + (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));
+    } 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));
     }
 
     if (Clearcoat != 0.0) {
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 8e31eaa..64a290d 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -137,14 +137,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;
-			uint tmp0, tmp1;
+			uint specular_offset, roughness_offset, specularTint_offset, anisotropic_offset, sheen_offset,
+				sheenTint_offset, clearcoat_offset, clearcoatGloss_offset, eta_offset, transparency_offset, refr_roughness_offset;
+			uint tmp0;
 			uint4 data_node2 = read_node(kg, offset);
 
 			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, &tmp0, &tmp1);
+			decode_node_uchar4(data_node2.x, &eta_offset, &transparency_offset, &refr_roughness_offset, &tmp0);
 
 			// get disney parameters
 			float metallic = param1;
@@ -158,6 +158,8 @@ 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 eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
 
 			eta = (ccl_fetch(sd, flag) & SD_BACKFACING) ? 1.0f / eta : eta;
@@ -170,10 +172,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 			float diffuse_weight = (1.0f - clamp(metallic, 0.0f, 1.0f)) * (1.0f - clamp(transparency, 0.0f, 1.0f)); // lerp(1.0f - clamp(metallic, 0.0f, 1.0f), 0.0f, lerp(clamp(transparency, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f)));
 			
 			float transp = clamp(transparency, 0.0f, 1.0f) * (1.0f - clamp(metallic, 0.0f, 1.0f)); // lerp(clamp(transparency, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f));
-			float specular_weight = 1.0f * (1.0f - transp) + fresnel * transp; // lerp(1.0f, fresnel, transp);
-			if (specular == 0.0f && metallic == 0.0f) {
-				specular_weight = 1.0f - transparency;
-			}
+			float specular_weight = (1.0f - transp); // + fresnel * transp; // lerp(1.0f, fresnel, transp);
 
 			// get the base color
 			uint4 data_base_color = read_node(kg, offset);
@@ -311,7 +310,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 
 						sc->color0 = baseColor;
 						sc->data0 = metallic;
-						sc->data1 = specular;
+						sc->data1 = specular; // (1.0f - transparency) * specular + transparency * specular * 12.5f/* equals division by 0.08f */;
 						sc->data2 = specularTint;
 						sc->data3 = roughness;
 						sc->data4 = anisotropic;
@@ -321,8 +320,66 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 				}
 			}
 
-			/* specular refraction */
+			/* BSDF */
 			if (specular_weight < 1.0f) {
+				if (ccl_fetch(sd, num_closure) + 1 < MAX_CLOSURE) {
+#ifdef __CAUSTICS_TRICKS__
+					if (!kernel_data.integrator.caustics_reflective &&
+						!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
+					{
+						break;
+					}
+#endif
+
+					/* reflection */
+					sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure));
+					sc->weight = weight;
+					sc->sample_weight = sample_weight;
+
+					sc = svm_node_closure_get_bsdf(sd, mix_weight * (1.0f - specular_weight) * fresnel);
+#ifdef __CAUSTICS_TRICKS__
+					if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
+#endif
+					{
+						if (sc) {
+							sc->N = N;
+							sc->T = stack_load_float3(stack, data_node.y);
+
+							sc->color0 = baseColor;
+							sc->data0 = 0.0f;
+							sc->data1 = 12.5f; // == (1.0f / 0.08f)
+							sc->data2 = specularTint;
+							sc->data3 = roughness;
+							sc->data4 = 0.0f;
+
+							ccl_fetch(sd, flag) |= bsdf_disney_specular_setup(sc);
+						}
+					}
+
+#ifdef __CAUSTICS_TRICKS__
+					if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
+						break;
+#endif
+
+					/* refraction */
+					sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure));
+					sc->weight = weight * baseColor;
+					sc->sample_weight = sample_weight;
+
+					sc = svm_node_closure_get_bsdf(sd, mix_weight * (1.0f - specular_weight) * (1.0f - fresnel));
+
+					if (sc) {
+						sc->N = N;
+						sc->data0 = refr_roughness * refr_roughness;
+						sc->data1 = refr_roughness * refr_roughness;
+						sc->data2 = eta;
+
+						ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(sc);
+					}
+				}
+			}
+			/* specular refraction */
+			/*if (specular_weight < 1.0f) {
 				if (ccl_fetch(sd, num_closure) < MAX_CLOSURE) {
 					sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure));
 					sc->weight = weight * baseColor;
@@ -333,14 +390,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 					if (sc) {
 						sc->N = N;
 
-						sc->data0 = roughness * roughness;
-						sc->data1 = roughness * roughness;
+						sc->data0 = refr_roughness * refr_roughness;
+						sc->data1 = refr_roughness * refr_roughness;
 						sc->data2 = eta;
 
 						ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(sc);
 					}
 				}
-			}
+			}*/
 
 			/* clearcoat */
 			if (clearcoat > 0.0f) {
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index f4c760d..00f6d16 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2127,6 +2127,7 @@ DisneyBsdfNode::DisneyBsdfNode()
 	add_input("ClearcoatGloss", SHADER_SOCKET_FLOAT, 1.0f);
 	add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f);
 	add_input("Transparency", SHADER_SOCKET_FLOAT, 0.0f);
+	add_input("RefractionRoughness", SHADER_SOCKET_FLOAT, 0.0f);
 	add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
 	add_input("ClearcoatNormal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
 	add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
@@ -2138,7 +2139,7 @@ DisneyBsdfNode::DisneyBsdfNode()
 void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface,
 	ShaderInput *specular, ShaderInput *roughness, ShaderInput *specularTint, ShaderInput *anisotropic,
 	ShaderInput *sheen, ShaderInput *sheenTint, ShaderInput *clearcoat, ShaderInput *clearcoatGloss,
-	ShaderInput *ior, ShaderInput *transparency)
+	ShaderInput *ior, ShaderInput *transparency, ShaderInput *refr_roughness)
 {
 	ShaderInput *base_color_in = input("BaseColor");
 	ShaderInput *normal_in = input("Normal");
@@ -2166,6 +2167,7 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *metallic, Shade
 	int clearcoatGloss_offset = compiler.stack_assign(clearcoatGloss);
 	int ior_offset = compiler.stack_assign(ior);
 	int transparency_offset = com

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list