[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