[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