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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to