forked from bartvdbraak/blender
Cycles: BSDF changes in preparation of path guiding
* Return roughness and IOR for BSDF sampling * Add functions to query IOR and label for given BSDF * Default IOR to 1.0 instead of 0.0 for BSDFs that don't use it * Ensure pdf >= 0.0 in case of numerical precision issues Ref T92571, D15286
This commit is contained in:
parent
715c86d9e5
commit
bd249eb4f3
@ -105,7 +105,9 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
/* For curves use the smooth normal, particularly for ribbons the geometric
|
||||
* normal gives too much darkening otherwise. */
|
||||
@ -115,78 +117,131 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
#if defined(__SVM__) || defined(__OSL__)
|
||||
case CLOSURE_BSDF_OREN_NAYAR_ID:
|
||||
label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
# ifdef __OSL__
|
||||
case CLOSURE_BSDF_PHONG_RAMP_ID:
|
||||
label = bsdf_phong_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_phong_ramp_sample(
|
||||
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
|
||||
label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
# endif
|
||||
case CLOSURE_BSDF_TRANSLUCENT_ID:
|
||||
label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_REFLECTION_ID:
|
||||
label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
|
||||
*sampled_roughness = zero_float2();
|
||||
break;
|
||||
case CLOSURE_BSDF_REFRACTION_ID:
|
||||
label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
|
||||
*sampled_roughness = zero_float2();
|
||||
break;
|
||||
case CLOSURE_BSDF_TRANSPARENT_ID:
|
||||
label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = zero_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
label = bsdf_microfacet_ggx_sample(kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_microfacet_ggx_sample(
|
||||
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
|
||||
label = bsdf_microfacet_multi_ggx_sample(
|
||||
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state);
|
||||
label = bsdf_microfacet_multi_ggx_sample(kg,
|
||||
sc,
|
||||
Ng,
|
||||
sd->I,
|
||||
randu,
|
||||
randv,
|
||||
eval,
|
||||
omega_in,
|
||||
pdf,
|
||||
&sd->lcg_state,
|
||||
sampled_roughness,
|
||||
eta);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
|
||||
label = bsdf_microfacet_multi_ggx_glass_sample(
|
||||
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state);
|
||||
label = bsdf_microfacet_multi_ggx_glass_sample(kg,
|
||||
sc,
|
||||
Ng,
|
||||
sd->I,
|
||||
randu,
|
||||
randv,
|
||||
eval,
|
||||
omega_in,
|
||||
pdf,
|
||||
&sd->lcg_state,
|
||||
sampled_roughness,
|
||||
eta);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
label = bsdf_microfacet_beckmann_sample(
|
||||
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
label = bsdf_ashikhmin_shirley_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_ashikhmin_shirley_sample(
|
||||
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
|
||||
label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_GLOSSY_TOON_ID:
|
||||
label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
// double check if this is valid
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
|
||||
label = bsdf_hair_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_hair_reflection_sample(
|
||||
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
|
||||
label = bsdf_hair_transmission_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_hair_transmission_sample(
|
||||
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||
label = bsdf_principled_hair_sample(kg, sc, sd, randu, randv, eval, omega_in, pdf);
|
||||
label = bsdf_principled_hair_sample(
|
||||
kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
|
||||
break;
|
||||
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
|
||||
label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
|
||||
label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
*sampled_roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -226,6 +281,246 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
return label;
|
||||
}
|
||||
|
||||
ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
||||
ccl_private const ShaderClosure *sc,
|
||||
ccl_private float2 *roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
bool refractive = false;
|
||||
float alpha = 1.0f;
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
#ifdef __SVM__
|
||||
case CLOSURE_BSDF_OREN_NAYAR_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
# ifdef __OSL__
|
||||
case CLOSURE_BSDF_PHONG_RAMP_ID:
|
||||
alpha = phong_ramp_exponent_to_roughness(((ccl_private const PhongRampBsdf *)sc)->exponent);
|
||||
*roughness = make_float2(alpha, alpha);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
# endif
|
||||
case CLOSURE_BSDF_TRANSLUCENT_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_REFLECTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = zero_float2();
|
||||
*eta = bsdf->ior;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_REFRACTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = zero_float2();
|
||||
// do we need to inverse eta??
|
||||
*eta = bsdf->ior;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_TRANSPARENT_ID:
|
||||
*roughness = zero_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
*eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
*eta = bsdf->ior;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
*eta = bsdf->ior;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
|
||||
*eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
|
||||
} break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_GLOSSY_TOON_ID:
|
||||
// double check if this is valid
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
|
||||
*roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1,
|
||||
((ccl_private HairBsdf *)sc)->roughness2);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
|
||||
*roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1,
|
||||
((ccl_private HairBsdf *)sc)->roughness2);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||
alpha = ((ccl_private PrincipledHairBSDF *)sc)->m0_roughness;
|
||||
*roughness = make_float2(alpha, alpha);
|
||||
*eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
|
||||
break;
|
||||
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline int bsdf_label(const KernelGlobals kg,
|
||||
ccl_private const ShaderClosure *sc,
|
||||
const float3 omega_in)
|
||||
{
|
||||
/* For curves use the smooth normal, particularly for ribbons the geometric
|
||||
* normal gives too much darkening otherwise. */
|
||||
int label;
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
case CLOSURE_BSSRDF_BURLEY_ID:
|
||||
case CLOSURE_BSSRDF_RANDOM_WALK_ID:
|
||||
case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
#ifdef __SVM__
|
||||
case CLOSURE_BSDF_OREN_NAYAR_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
# ifdef __OSL__
|
||||
case CLOSURE_BSDF_PHONG_RAMP_ID:
|
||||
label = LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
# endif
|
||||
case CLOSURE_BSDF_TRANSLUCENT_ID:
|
||||
label = LABEL_TRANSMIT | LABEL_DIFFUSE;
|
||||
break;
|
||||
case CLOSURE_BSDF_REFLECTION_ID:
|
||||
label = LABEL_REFLECT | LABEL_SINGULAR;
|
||||
break;
|
||||
case CLOSURE_BSDF_REFRACTION_ID:
|
||||
label = LABEL_TRANSMIT | LABEL_SINGULAR;
|
||||
break;
|
||||
case CLOSURE_BSDF_TRANSPARENT_ID:
|
||||
label = LABEL_TRANSMIT | LABEL_TRANSPARENT;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_REFLECT | LABEL_SINGULAR :
|
||||
LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_TRANSMIT | LABEL_SINGULAR :
|
||||
LABEL_TRANSMIT | LABEL_GLOSSY;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
|
||||
label = (bsdf_is_transmission(sc, omega_in)) ? LABEL_TRANSMIT | LABEL_GLOSSY :
|
||||
LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
label = LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
case CLOSURE_BSDF_GLOSSY_TOON_ID:
|
||||
label = LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
|
||||
label = LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
|
||||
label = LABEL_TRANSMIT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||
if (is_transmission)
|
||||
label = LABEL_TRANSMIT | LABEL_GLOSSY;
|
||||
else
|
||||
label = LABEL_REFLECT | LABEL_GLOSSY;
|
||||
break;
|
||||
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
|
||||
label = LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
label = LABEL_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Test if BSDF sample should be treated as transparent for background. */
|
||||
if (label & LABEL_TRANSMIT) {
|
||||
float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
|
||||
|
||||
if (threshold_squared >= 0.0f) {
|
||||
if (bsdf_get_specular_roughness_squared(sc) <= threshold_squared) {
|
||||
label |= LABEL_TRANSMIT_TRANSPARENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
#ifndef __KERNEL_CUDA__
|
||||
ccl_device
|
||||
#else
|
||||
|
@ -137,9 +137,11 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
float3 N = bsdf->N;
|
||||
int label = LABEL_REFLECT | LABEL_GLOSSY;
|
||||
|
||||
|
@ -155,13 +155,15 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness)
|
||||
{
|
||||
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
|
||||
float offset = bsdf->offset;
|
||||
float3 Tg = bsdf->T;
|
||||
float roughness1 = bsdf->roughness1;
|
||||
float roughness2 = bsdf->roughness2;
|
||||
*sampled_roughness = make_float2(roughness1, roughness2);
|
||||
float Iz = dot(Tg, I);
|
||||
float3 locy = normalize(I - Tg * Iz);
|
||||
float3 locx = cross(locy, Tg);
|
||||
@ -206,13 +208,15 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness)
|
||||
{
|
||||
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
|
||||
float offset = bsdf->offset;
|
||||
float3 Tg = bsdf->T;
|
||||
float roughness1 = bsdf->roughness1;
|
||||
float roughness2 = bsdf->roughness2;
|
||||
*sampled_roughness = make_float2(roughness1, roughness2);
|
||||
float Iz = dot(Tg, I);
|
||||
float3 locy = normalize(I - Tg * Iz);
|
||||
float3 locx = cross(locy, Tg);
|
||||
|
@ -354,10 +354,15 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
|
||||
|
||||
*sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
|
||||
*eta = bsdf->eta;
|
||||
|
||||
float3 Y = float4_to_float3(bsdf->extra->geom);
|
||||
|
||||
float3 X = safe_normalize(sd->dPdu);
|
||||
|
@ -541,12 +541,18 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
float alpha_x = bsdf->alpha_x;
|
||||
float alpha_y = bsdf->alpha_y;
|
||||
bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
|
||||
*sampled_roughness = make_float2(alpha_x, alpha_y);
|
||||
*eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior;
|
||||
|
||||
float3 N = bsdf->N;
|
||||
int label;
|
||||
|
||||
@ -952,7 +958,9 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
float alpha_x = bsdf->alpha_x;
|
||||
@ -961,6 +969,9 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
|
||||
float3 N = bsdf->N;
|
||||
int label;
|
||||
|
||||
*sampled_roughness = make_float2(alpha_x, alpha_y);
|
||||
*eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior;
|
||||
|
||||
float cosNO = dot(N, I);
|
||||
if (cosNO > 0) {
|
||||
float3 X, Y, Z = N;
|
||||
|
@ -462,6 +462,12 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Sha
|
||||
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
|
||||
else
|
||||
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
|
||||
|
||||
if (*pdf <= 0.f) {
|
||||
*pdf = 0.f;
|
||||
return make_float3(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
return mf_eval_glossy(localI,
|
||||
localO,
|
||||
true,
|
||||
@ -483,7 +489,9 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf,
|
||||
ccl_private uint *lcg_state)
|
||||
ccl_private uint *lcg_state,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
|
||||
@ -511,6 +519,9 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
|
||||
|
||||
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
|
||||
|
||||
*eta = bsdf->ior;
|
||||
*sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
|
||||
bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
|
||||
if (is_aniso)
|
||||
make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
|
||||
@ -541,6 +552,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
|
||||
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
|
||||
else
|
||||
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
|
||||
*pdf = fmaxf(0.f, *pdf);
|
||||
*eval *= *pdf;
|
||||
|
||||
return LABEL_REFLECT | LABEL_GLOSSY;
|
||||
@ -598,6 +610,7 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s
|
||||
float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
|
||||
|
||||
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
|
||||
kernel_assert(*pdf >= 0.f);
|
||||
return mf_eval_glass(localI,
|
||||
localO,
|
||||
false,
|
||||
@ -634,6 +647,7 @@ bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc
|
||||
float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
|
||||
|
||||
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
|
||||
kernel_assert(*pdf >= 0.f);
|
||||
return mf_eval_glass(localI,
|
||||
localO,
|
||||
true,
|
||||
@ -655,13 +669,18 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf,
|
||||
ccl_private uint *lcg_state)
|
||||
ccl_private uint *lcg_state,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
|
||||
float3 X, Y, Z;
|
||||
Z = bsdf->N;
|
||||
|
||||
*eta = bsdf->ior;
|
||||
*sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
|
||||
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
|
||||
float3 R, T;
|
||||
bool inside;
|
||||
@ -696,6 +715,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
|
||||
use_fresnel,
|
||||
bsdf->extra->cspec0);
|
||||
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
|
||||
kernel_assert(*pdf >= 0.f);
|
||||
*eval *= *pdf;
|
||||
|
||||
*omega_in = X * localO.x + Y * localO.y + Z * localO.z;
|
||||
|
@ -79,6 +79,11 @@ ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
ccl_device_inline float phong_ramp_exponent_to_roughness(float exponent)
|
||||
{
|
||||
return sqrt(1.0f / ((exponent + 2.0f) / 2.0f));
|
||||
}
|
||||
|
||||
ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
|
||||
float3 Ng,
|
||||
float3 I,
|
||||
@ -86,11 +91,14 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness)
|
||||
{
|
||||
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
|
||||
float cosNO = dot(bsdf->N, I);
|
||||
float m_exponent = bsdf->exponent;
|
||||
const float m_roughness = phong_ramp_exponent_to_roughness(m_exponent);
|
||||
*sampled_roughness = make_float2(m_roughness, m_roughness);
|
||||
|
||||
if (cosNO > 0) {
|
||||
// reflect the view vector
|
||||
|
@ -43,10 +43,12 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
float3 N = bsdf->N;
|
||||
*eta = bsdf->ior;
|
||||
|
||||
// only one direction is possible
|
||||
float cosNO = dot(N, I);
|
||||
|
@ -43,10 +43,13 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
|
||||
float randv,
|
||||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
float m_eta = bsdf->ior;
|
||||
|
||||
*eta = 1.0f / m_eta;
|
||||
float3 N = bsdf->N;
|
||||
|
||||
float3 R, T;
|
||||
|
@ -357,8 +357,18 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
|
||||
float3 bsdf_omega_in ccl_optional_struct_init;
|
||||
int label;
|
||||
|
||||
label = surface_shader_bsdf_sample_closure(
|
||||
kg, sd, sc, rand_bsdf, &bsdf_eval, &bsdf_omega_in, &bsdf_pdf);
|
||||
float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f);
|
||||
float bsdf_eta = 1.0f;
|
||||
|
||||
label = surface_shader_bsdf_sample_closure(kg,
|
||||
sd,
|
||||
sc,
|
||||
rand_bsdf,
|
||||
&bsdf_eval,
|
||||
&bsdf_omega_in,
|
||||
&bsdf_pdf,
|
||||
&bsdf_sampled_roughness,
|
||||
&bsdf_eta);
|
||||
|
||||
if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
|
||||
return LABEL_NONE;
|
||||
|
@ -267,7 +267,9 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
|
||||
const float2 rand_bsdf,
|
||||
ccl_private BsdfEval *bsdf_eval,
|
||||
ccl_private float3 *omega_in,
|
||||
ccl_private float *pdf)
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
/* BSSRDF should already have been handled elsewhere. */
|
||||
kernel_assert(CLOSURE_IS_BSDF(sc->type));
|
||||
@ -276,7 +278,8 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
|
||||
Spectrum eval = zero_spectrum();
|
||||
|
||||
*pdf = 0.0f;
|
||||
label = bsdf_sample(kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, pdf);
|
||||
label = bsdf_sample(
|
||||
kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, pdf, sampled_roughness, eta);
|
||||
|
||||
if (*pdf != 0.0f) {
|
||||
bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight);
|
||||
|
@ -428,7 +428,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_setup(
|
||||
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
|
||||
bsdf->alpha_x = closure->alpha_x;
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
bsdf->ior = 0.0f;
|
||||
bsdf->ior = 1.0f;
|
||||
|
||||
bsdf->extra = extra;
|
||||
bsdf->extra->color = rgb_to_spectrum(closure->color);
|
||||
@ -510,7 +510,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
|
||||
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
|
||||
bsdf->alpha_x = closure->alpha_x;
|
||||
bsdf->alpha_y = closure->alpha_y;
|
||||
bsdf->ior = 0.0f;
|
||||
bsdf->ior = 1.0f;
|
||||
|
||||
bsdf->extra = extra;
|
||||
bsdf->extra->color = rgb_to_spectrum(closure->color);
|
||||
|
@ -31,7 +31,7 @@ ccl_device void svm_node_glass_setup(ccl_private ShaderData *sd,
|
||||
else {
|
||||
bsdf->alpha_y = 0.0f;
|
||||
bsdf->alpha_x = 0.0f;
|
||||
bsdf->ior = 0.0f;
|
||||
bsdf->ior = eta;
|
||||
sd->flag |= bsdf_reflection_setup(bsdf);
|
||||
}
|
||||
}
|
||||
@ -542,7 +542,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
float roughness = sqr(param1);
|
||||
|
||||
bsdf->N = N;
|
||||
bsdf->ior = 0.0f;
|
||||
bsdf->ior = 1.0f;
|
||||
bsdf->extra = NULL;
|
||||
|
||||
if (data_node.y == SVM_STACK_INVALID) {
|
||||
|
Loading…
Reference in New Issue
Block a user