[Bf-blender-cvs] [10974cc] cycles_disney_brdf: Added parameters IOR and Transparency for refractions

Pascal Schoen noreply at git.blender.org
Tue May 31 11:19:58 CEST 2016


Commit: 10974cc826a4bfa8fb3ef59177abf0b0dc441065
Author: Pascal Schoen
Date:   Tue May 31 11:18:07 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rB10974cc826a4bfa8fb3ef59177abf0b0dc441065

Added parameters IOR and Transparency for refractions

With this, the Disney BRDF/BSSRDF is extended by the BTDF part.

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

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 c6d75c4..b6312c6 100644
--- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
@@ -15,6 +15,7 @@
  */
 
 #include "stdosl.h"
+#include "node_fresnel.h"
 
 shader node_disney_bsdf(
 	color BaseColor = color(0.64555527, 0.41514809, 0.01698805),
@@ -28,40 +29,37 @@ shader node_disney_bsdf(
     float SheenTint = 0.5,
     float Clearcoat = 0.0,
     float ClearcoatGloss = 1.0,
+    float IOR = 1.45,
+    float Transparency = 0.0,
 	normal Normal = N,
 	normal ClearcoatNormal = N,
 	normal Tangent = normalize(dPdu),
     //normal AnisotropicRotation = normal(0, 0, 0),
 	output closure color BSDF = 0)
 {
-    if (Metallic != 1.0) {
+	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));
+    
+    if (metal < 1.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 - Metallic);
+                + disney_sheen(Normal, BaseColor, Sheen, SheenTint)) * (1.0 - metal) * (1.0 - trans);
     }
 
     if (Specular != 0.0 || Metallic != 0.0) {
-        BSDF = BSDF + disney_specular(Normal, Tangent, BaseColor, Metallic, Specular,
-                                      SpecularTint, Roughness, Anisotropic);
+        BSDF = BSDF + specWeight * 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);
     }
 
     if (Clearcoat != 0.0) {
         BSDF = BSDF + disney_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatGloss);
     }
-
-	/*if (Metallic == 1.0) {
-        BSDF =  disney_specular(Normal, Tangent, BaseColor, Metallic, Specular,
-                                  SpecularTint, Roughness, Anisotropic)
-                + disney_clearcoat(Normal, Clearcoat, ClearcoatGloss);
-    } else if (Specular == 0.0 && Metallic == 0.0) {
-        BSDF =  disney_diffuse(Normal, BaseColor, Subsurface, Roughness,
-                               Sheen, SheenTint) * (1.0 - Metallic)
-                + disney_clearcoat(Normal, Clearcoat, ClearcoatGloss);
-    } else {
-        BSDF =  disney_diffuse(Normal, BaseColor, Subsurface, Roughness,
-                               Sheen, SheenTint) * (1.0 - Metallic)
-                + disney_specular(Normal, Tangent, BaseColor, Metallic, Specular,
-                                  SpecularTint, Roughness, Anisotropic)
-                + disney_clearcoat(Normal, Clearcoat, ClearcoatGloss);
-    }*/
 }
 
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index fadddbc..ac282a1 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -138,10 +138,15 @@ 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;
+				sheen_offset, sheenTint_offset, clearcoat_offset, clearcoatGloss_offset, eta_offset, transparency_offset;
+			uint tmp0, tmp1;
+			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);
 
+			// get disney parameters
 			float metallic = param1;
 			float subsurface = param2;
 			float specular = stack_load_float(stack, specular_offset);
@@ -152,11 +157,28 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 			float sheenTint = stack_load_float(stack, sheenTint_offset);
 			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 eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
+
+			eta = (ccl_fetch(sd, flag) & SD_BACKFACING) ? 1.0f / eta : eta;
+
+			// calculate fresnel for refraction
+			float cosNO = dot(N, ccl_fetch(sd, I));
+			float fresnel = fresnel_dielectric_cos(cosNO, eta);
 
+			// calculate weights of the diffuse and specular part
+			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 specular_weight = lerp(1.0f, fresnel, lerp(clamp(transparency, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f)));
+			if (specular == 0.0f && metallic == 0.0f) {
+				specular_weight = 1.0f - transparency;
+			}
+
+			// get the base color
 			uint4 data_base_color = read_node(kg, offset);
 			float3 baseColor = stack_valid(data_base_color.x) ? stack_load_float3(stack, data_base_color.x) :
 				make_float3(__uint_as_float(data_base_color.y), __uint_as_float(data_base_color.z), __uint_as_float(data_base_color.w));
 
+			// get the additional clearcoat normal
 			uint4 data_clearcoat_normal = read_node(kg, offset);
 			float3 CN = stack_valid(data_clearcoat_normal.x) ? stack_load_float3(stack, data_clearcoat_normal.x) : ccl_fetch(sd, N);
             
@@ -166,7 +188,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 
 			/* subsurface */
 			float3 albedo = baseColor;
-			float3 subsurf_weight = baseColor * sc->weight * mix_weight * subsurface * (1.0f - clamp(metallic, 0.0f, 1.0f));
+			float3 subsurf_weight = baseColor * sc->weight * mix_weight * subsurface * diffuse_weight;
 			float subsurf_sample_weight = fabsf(average(subsurf_weight));
 
 			if (subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure) + 2 < MAX_CLOSURE) {
@@ -238,7 +260,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 					sc->weight = weight;
 					sc->sample_weight = sample_weight;
 
-					sc = svm_node_closure_get_bsdf(sd, mix_weight * (1.0f - clamp(subsurface, 0.0f, 1.0f)) * (1.0f - clamp(metallic, 0.0f, 1.0f)));
+					sc = svm_node_closure_get_bsdf(sd, mix_weight * (1.0f - clamp(subsurface, 0.0f, 1.0f)) * diffuse_weight);
 
 					if (sc) {
 						sc->N = N;
@@ -258,7 +280,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 					sc->weight = weight;
 					sc->sample_weight = sample_weight;
 
-                    sc = svm_node_closure_get_bsdf(sd, mix_weight * (1.0f - clamp(metallic, 0.0f, 1.0f)));
+					sc = svm_node_closure_get_bsdf(sd, mix_weight * diffuse_weight);
                     
                     if (sc) {
                         sc->N = N;
@@ -272,14 +294,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
                 }
 			}
 
-			/* specular */
-			if (specular > 0.0f || metallic > 0.0f) {
+			/* specular reflection */
+			if (specular != 0.0f || metallic != 0.0f) {
 				if (ccl_fetch(sd, num_closure) < MAX_CLOSURE) {
 					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/* * mix(0.333f, 0.5f, clamp(metallic, 0.0f, 1.0f))*/);
+					sc = svm_node_closure_get_bsdf(sd, mix_weight * specular_weight);
 
 					if (sc) {
 						sc->N = N;
@@ -297,6 +319,27 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 				}
 			}
 
+			/* 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;
+					sc->sample_weight = sample_weight;
+
+					sc = svm_node_closure_get_bsdf(sd, mix_weight * (1.0f - specular_weight));
+
+					if (sc) {
+						sc->N = N;
+
+						sc->data0 = roughness * roughness;
+						sc->data1 = roughness * roughness;
+						sc->data2 = eta;
+
+						ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(sc);
+					}
+				}
+			}
+
 			/* clearcoat */
 			if (clearcoat > 0.0f) {
 				if (ccl_fetch(sd, num_closure) < MAX_CLOSURE) {
@@ -304,7 +347,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
 					sc->weight = weight;
 					sc->sample_weight = sample_weight;
 
-					sc = svm_node_closure_get_bsdf(sd, mix_weight/* * mix(0.333f, 0.5f, clamp(metallic, 0.0f, 1.0f))*/);
+					sc = svm_node_closure_get_bsdf(sd, mix_weight);
 
 					if (sc) {
 						sc->N = CN;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 31f2664..f4c760d 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2125,6 +2125,8 @@ DisneyBsdfNode::DisneyBsdfNode()
 	add_input("SheenTint", SHADER_SOCKET_FLOAT, 0.5f);
 	add_input("Clearcoat", SHADER_SOCKET_FLOAT, 0.0f);
 	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("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
 	add_input("ClearcoatNormal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
 	add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
@@ -2135,7 +2137,8 @@ DisneyBsdfNode::DisneyBsdfNode()
 
 void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list