Improvement of the SSS in the Disney shader
* Now the bump normal is correctly used for the SSS. * SSS in Disney uses the Disney diffuse shader
This commit is contained in:
@@ -121,6 +121,7 @@ ccl_device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const Shader
|
||||
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
|
||||
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
|
||||
label = bsdf_disney_diffuse_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
|
||||
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
|
||||
break;
|
||||
@@ -217,6 +218,7 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
|
||||
eval = bsdf_hair_transmission_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
|
||||
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
|
||||
eval = bsdf_disney_diffuse_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
|
||||
@@ -291,6 +293,7 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
|
||||
eval = bsdf_hair_transmission_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
|
||||
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
|
||||
eval = bsdf_disney_diffuse_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
|
||||
|
||||
@@ -329,10 +329,20 @@ ccl_device int bssrdf_setup(ShaderClosure *sc, ClosureType type)
|
||||
{
|
||||
if(sc->data0 < BSSRDF_MIN_RADIUS) {
|
||||
/* revert to diffuse BSDF if radius too small */
|
||||
sc->data0 = 0.0f;
|
||||
sc->data1 = 0.0f;
|
||||
int flag = bsdf_diffuse_setup(sc);
|
||||
sc->type = CLOSURE_BSDF_BSSRDF_ID;
|
||||
int flag;
|
||||
if (type == CLOSURE_BSSRDF_DISNEY_ID) {
|
||||
sc->data0 = sc->data3;
|
||||
sc->data1 = 0.0f;
|
||||
flag = bsdf_disney_diffuse_setup(sc);
|
||||
sc->type = CLOSURE_BSDF_BSSRDF_DISNEY_ID;
|
||||
}
|
||||
else {
|
||||
sc->data0 = 0.0f;
|
||||
sc->data1 = 0.0f;
|
||||
flag = bsdf_diffuse_setup(sc);
|
||||
sc->type = CLOSURE_BSDF_BSSRDF_ID;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
else {
|
||||
@@ -340,7 +350,7 @@ ccl_device int bssrdf_setup(ShaderClosure *sc, ClosureType type)
|
||||
sc->T.x = saturate(sc->T.x); /* sharpness */
|
||||
sc->type = type;
|
||||
|
||||
if(type == CLOSURE_BSSRDF_BURLEY_ID) {
|
||||
if (type == CLOSURE_BSSRDF_BURLEY_ID || type == CLOSURE_BSSRDF_DISNEY_ID) {
|
||||
bssrdf_burley_setup(sc);
|
||||
}
|
||||
|
||||
@@ -354,7 +364,7 @@ ccl_device void bssrdf_sample(ShaderClosure *sc, float xi, float *r, float *h)
|
||||
bssrdf_cubic_sample(sc, xi, r, h);
|
||||
else if(sc->type == CLOSURE_BSSRDF_GAUSSIAN_ID)
|
||||
bssrdf_gaussian_sample(sc, xi, r, h);
|
||||
else /*if(sc->type == CLOSURE_BSSRDF_BURLEY_ID)*/
|
||||
else /*if(sc->type == CLOSURE_BSSRDF_BURLEY_ID || sc->type == CLOSURE_BSSRDF_DISNEY_ID)*/
|
||||
bssrdf_burley_sample(sc, xi, r, h);
|
||||
}
|
||||
|
||||
@@ -364,7 +374,7 @@ ccl_device float bssrdf_pdf(ShaderClosure *sc, float r)
|
||||
return bssrdf_cubic_pdf(sc, r);
|
||||
else if(sc->type == CLOSURE_BSSRDF_GAUSSIAN_ID)
|
||||
return bssrdf_gaussian_pdf(sc, r);
|
||||
else /*if(sc->type == CLOSURE_BSSRDF_BURLEY_ID)*/
|
||||
else /*if(sc->type == CLOSURE_BSSRDF_BURLEY_ID || sc->type == CLOSURE_BSSRDF_DISNEY_ID)*/
|
||||
return bssrdf_burley_pdf(sc, r);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,14 +147,24 @@ ccl_device void subsurface_scatter_setup_diffuse_bsdf(ShaderData *sd, float3 wei
|
||||
|
||||
sc->weight = weight;
|
||||
sc->sample_weight = 1.0f;
|
||||
sc->data0 = 0.0f;
|
||||
sc->data1 = 0.0f;
|
||||
sc->N = N;
|
||||
sd->flag |= bsdf_diffuse_setup(sc);
|
||||
if (sc->type == CLOSURE_BSSRDF_DISNEY_ID) {
|
||||
sc->data0 = sc->data3;
|
||||
sd->flag |= bsdf_disney_diffuse_setup(sc);
|
||||
|
||||
/* replace CLOSURE_BSDF_DIFFUSE_ID with this special ID so render passes
|
||||
* can recognize it as not being a regular diffuse closure */
|
||||
sc->type = CLOSURE_BSDF_BSSRDF_ID;
|
||||
/* replace CLOSURE_BSDF_DISNEY_DIFFUSE_ID with this special ID so render passes
|
||||
* can recognize it as not being a regular Disney diffuse closure */
|
||||
sc->type = CLOSURE_BSDF_BSSRDF_DISNEY_ID;
|
||||
}
|
||||
else {
|
||||
sc->data0 = 0.0f;
|
||||
sc->data1 = 0.0f;
|
||||
sd->flag |= bsdf_diffuse_setup(sc);
|
||||
|
||||
/* replace CLOSURE_BSDF_DIFFUSE_ID with this special ID so render passes
|
||||
* can recognize it as not being a regular diffuse closure */
|
||||
sc->type = CLOSURE_BSDF_BSSRDF_ID;
|
||||
}
|
||||
}
|
||||
else
|
||||
sd->num_closure = 0;
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
#include "kernel_types.h"
|
||||
#include "kernel_montecarlo.h"
|
||||
|
||||
#include "closure/bsdf_util.h"
|
||||
#include "closure/bsdf_diffuse.h"
|
||||
#include "closure/bsdf_disney_diffuse.h"
|
||||
#include "closure/bssrdf.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
|
||||
#include "geom/geom_object.h"
|
||||
|
||||
#include "closure/bsdf_util.h"
|
||||
#include "closure/bsdf_diffuse.h"
|
||||
#include "closure/bsdf_disney_diffuse.h"
|
||||
#include "closure/bssrdf.h"
|
||||
|
||||
#include "osl_bssrdf.h"
|
||||
@@ -278,7 +280,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
|
||||
bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
float3 albedo =
|
||||
(bssrdf->sc.type == CLOSURE_BSSRDF_BURLEY_ID)
|
||||
(bssrdf->sc.type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->sc.type == CLOSURE_BSSRDF_DISNEY_ID)
|
||||
? bssrdf->albedo
|
||||
: make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
|
||||
@@ -193,19 +193,18 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
|
||||
#ifdef __SUBSURFACE__
|
||||
float3 albedo = baseColor;
|
||||
float3 subsurf_weight = baseColor * weight * saturate(subsurface) * diffuse_weight;
|
||||
float3 subsurf_weight = weight * diffuse_weight;
|
||||
float subsurf_sample_weight = fabsf(average(subsurf_weight));
|
||||
|
||||
/* disable in case of diffuse ancestor, can't see it well then and
|
||||
* adds considerably noise due to probabilities of continuing path
|
||||
* getting lower and lower */
|
||||
float radius_weight = 1.0f;
|
||||
if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
|
||||
radius_weight = 0.0f;
|
||||
if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
|
||||
subsurface = 0.0f;
|
||||
|
||||
if (subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure) + 2 < MAX_CLOSURE) {
|
||||
/* radius * scale */
|
||||
float3 radius = make_float3(1.0f, 1.0f, 1.0f) * radius_weight;
|
||||
float3 radius = make_float3(1.0f, 1.0f, 1.0f) * subsurface;
|
||||
/* sharpness */
|
||||
float sharpness = 0.0f;
|
||||
/* texture color blur */
|
||||
@@ -218,12 +217,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
sc->data0 = radius.x;
|
||||
sc->data1 = texture_blur;
|
||||
sc->data2 = albedo.x;
|
||||
sc->data3 = roughness;
|
||||
sc->T.x = sharpness;
|
||||
sc->color0 = baseColor;
|
||||
# ifdef __OSL__
|
||||
sc->prim = NULL;
|
||||
# endif
|
||||
sc->N = N;
|
||||
ccl_fetch(sd, flag) |= bssrdf_setup(sc, (ClosureType)CLOSURE_BSSRDF_BURLEY_ID);
|
||||
ccl_fetch(sd, flag) |= bssrdf_setup(sc, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
|
||||
|
||||
ccl_fetch(sd, num_closure)++;
|
||||
sc_next(sc);
|
||||
@@ -235,12 +236,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
sc->data0 = radius.y;
|
||||
sc->data1 = texture_blur;
|
||||
sc->data2 = albedo.y;
|
||||
sc->data3 = roughness;
|
||||
sc->T.x = sharpness;
|
||||
sc->color0 = baseColor;
|
||||
# ifdef __OSL__
|
||||
sc->prim = NULL;
|
||||
# endif
|
||||
sc->N = N;
|
||||
ccl_fetch(sd, flag) |= bssrdf_setup(sc, (ClosureType)CLOSURE_BSSRDF_BURLEY_ID);
|
||||
ccl_fetch(sd, flag) |= bssrdf_setup(sc, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
|
||||
|
||||
ccl_fetch(sd, num_closure)++;
|
||||
sc_next(sc);
|
||||
@@ -252,23 +255,24 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
sc->data0 = radius.z;
|
||||
sc->data1 = texture_blur;
|
||||
sc->data2 = albedo.z;
|
||||
sc->data3 = roughness;
|
||||
sc->T.x = sharpness;
|
||||
sc->color0 = baseColor;
|
||||
# ifdef __OSL__
|
||||
sc->prim = NULL;
|
||||
# endif
|
||||
sc->N = N;
|
||||
ccl_fetch(sd, flag) |= bssrdf_setup(sc, (ClosureType)CLOSURE_BSSRDF_BURLEY_ID);
|
||||
ccl_fetch(sd, flag) |= bssrdf_setup(sc, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
|
||||
|
||||
ccl_fetch(sd, num_closure)++;
|
||||
sc_next(sc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* diffuse */
|
||||
if ((1.0f - saturate(subsurface)) * diffuse_weight > 0.0f) {
|
||||
if (diffuse_weight > 0.0f) {
|
||||
if (ccl_fetch(sd, num_closure) < MAX_CLOSURE) {
|
||||
float3 diff_weight = weight * (1.0f - saturate(subsurface)) * diffuse_weight;
|
||||
float3 diff_weight = weight * diffuse_weight;
|
||||
float diff_sample_weight = fabsf(average(diff_weight));
|
||||
|
||||
if (diff_sample_weight > CLOSURE_WEIGHT_CUTOFF) {
|
||||
@@ -289,6 +293,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sheen */
|
||||
if (diffuse_weight > 0.0f && sheen != 0.0f) {
|
||||
|
||||
@@ -412,11 +412,13 @@ typedef enum ClosureType {
|
||||
|
||||
/* Special cases */
|
||||
CLOSURE_BSDF_BSSRDF_ID,
|
||||
CLOSURE_BSDF_BSSRDF_DISNEY_ID,
|
||||
CLOSURE_BSDF_TRANSPARENT_ID,
|
||||
|
||||
/* BSSRDF */
|
||||
CLOSURE_BSSRDF_CUBIC_ID,
|
||||
CLOSURE_BSSRDF_GAUSSIAN_ID,
|
||||
CLOSURE_BSSRDF_DISNEY_ID,
|
||||
CLOSURE_BSSRDF_BURLEY_ID,
|
||||
|
||||
/* Other */
|
||||
@@ -440,7 +442,7 @@ typedef enum ClosureType {
|
||||
#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)
|
||||
#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)
|
||||
#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
|
||||
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
|
||||
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_DISNEY_ID)
|
||||
#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type >= CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID)
|
||||
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_BURLEY_ID)
|
||||
#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID)
|
||||
|
||||
@@ -2202,6 +2202,13 @@ void DisneyBsdfNode::compile(OSLCompiler& compiler)
|
||||
compiler.add(this, "node_disney_bsdf");
|
||||
}
|
||||
|
||||
bool DisneyBsdfNode::has_bssrdf_bump()
|
||||
{
|
||||
/* detect if anything is plugged into the normal input besides the default */
|
||||
ShaderInput *normal_in = input("Normal");
|
||||
return (normal_in->link && normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY);
|
||||
}
|
||||
|
||||
/* Translucent BSDF Closure */
|
||||
|
||||
TranslucentBsdfNode::TranslucentBsdfNode()
|
||||
|
||||
@@ -420,6 +420,8 @@ public:
|
||||
SHADER_NODE_CLASS(DisneyBsdfNode)
|
||||
|
||||
bool has_spatial_varying() { return true; }
|
||||
bool has_surface_bssrdf() { return true; }
|
||||
bool has_bssrdf_bump();
|
||||
void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface,
|
||||
ShaderInput *specular, ShaderInput *roughness, ShaderInput *specularTint, ShaderInput *anisotropic,
|
||||
ShaderInput *sheen, ShaderInput *sheenTint, ShaderInput *clearcoat, ShaderInput *clearcoatGloss,
|
||||
|
||||
Reference in New Issue
Block a user