diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl index b6312c61002..b608b734546 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 8e31eaab447..64a290d3b72 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 f4c760d7205..00f6d168c97 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 = compiler.stack_assign(transparency); + int refr_roughness_offset = compiler.stack_assign(refr_roughness); compiler.add_node(NODE_CLOSURE_BSDF, compiler.encode_uchar4(closure, @@ -2179,7 +2181,7 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *metallic, Shade compiler.encode_uchar4(specular_offset, roughness_offset, specularTint_offset, anisotropic_offset), compiler.encode_uchar4(sheen_offset, sheenTint_offset, clearcoat_offset, clearcoatGloss_offset)); - compiler.add_node(compiler.encode_uchar4(ior_offset, transparency_offset, SVM_STACK_INVALID, SVM_STACK_INVALID), + compiler.add_node(compiler.encode_uchar4(ior_offset, transparency_offset, refr_roughness_offset, SVM_STACK_INVALID), SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID); compiler.add_node(((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID), @@ -2192,7 +2194,7 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler) { compile(compiler, input("Metallic"), input("Subsurface"), input("Specular"), input("Roughness"), input("SpecularTint"), input("Anisotropic"), input("Sheen"), input("SheenTint"), - input("Clearcoat"), input("ClearcoatGloss"), input("IOR"), input("Transparency")); + input("Clearcoat"), input("ClearcoatGloss"), input("IOR"), input("Transparency"), input("RefractionRoughness")); } void DisneyBsdfNode::compile(OSLCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 693d321738e..a509f30e67e 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -423,7 +423,7 @@ public: void 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); ClosureType closure; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c index 30c27e39f7c..f80b9a49f61 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c @@ -43,6 +43,7 @@ static bNodeSocketTemplate sh_node_bsdf_disney_in[] = { { SOCK_FLOAT, 1, N_("ClearcoatGloss"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("RefractionRoughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { SOCK_VECTOR, 1, N_("ClearcoatNormal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},