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)
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user