Cycles: Remove MultiGGX code, replace with albedo scaling #107958

Merged
Lukas Stockner merged 8 commits from LukasStockner/blender:remove-multiggx into main 2023-06-05 02:21:03 +02:00
8 changed files with 162 additions and 615 deletions
Showing only changes of commit 342fecc563 - Show all commits

View File

@ -698,23 +698,43 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
/* Fresnel term setup functions. These get called after the distribution-specific setup functions
* like bsdf_microfacet_ggx_setup. */
ccl_device void bsdf_microfacet_setup_fresnel_conductor(ccl_private MicrofacetBsdf *bsdf,
ccl_device void bsdf_microfacet_setup_fresnel_conductor(KernelGlobals kg,
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelConductor *fresnel)
ccl_private FresnelConductor *fresnel,
const bool preserve_energy)
{
bsdf->fresnel_type = MicrofacetFresnel::CONDUCTOR;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
if (preserve_energy) {
/* In order to estimate Fss of the conductor, we fit the F82-tint model to it based on the
* value at 0° and ~82° and then use the analytic expression for its Fss. */
Spectrum F0 = fresnel_conductor(1.0f, fresnel->n, fresnel->k);
Spectrum F82 = fresnel_conductor(1.0f / 7.0f, fresnel->n, fresnel->k);
/* 0.46266436f is (1 - 1/7)^5, 17.651384f is 1/(1/7 * (1 - 1/7)^6) */
Spectrum B = (mix(F0, one_spectrum(), 0.46266436f) - F82) * 17.651384f;
Spectrum Fss = saturate(mix(F0, one_spectrum(), 1.0f / 21.0f) - B * (1.0f / 126.0f));
microfacet_ggx_preserve_energy(kg, bsdf, sd, Fss);
}
}
ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint(
KernelGlobals kg,
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelDielectricTint *fresnel)
ccl_private FresnelDielectricTint *fresnel,
const bool preserve_energy)
{
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC_TINT;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
if (preserve_energy) {
/* Assume that the transmissive tint makes up most of the overall color. */
microfacet_ggx_preserve_energy(kg, bsdf, sd, fresnel->transmission_tint);
}
}
ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
@ -727,6 +747,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf));
if (preserve_energy) {
Spectrum Fss = one_spectrum();
/* Multi-bounce Fresnel is only supported for reflective lobes here. */
@ -755,6 +776,11 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
/* Due to the linearity of the generalized model, this ends up working. */
Fss = fresnel->reflection_tint * mix(fresnel->f0, fresnel->f90, s);
}
else {
/* For transmissive BSDFs, assume that the transmissive tint makes up most of the overall
* color. */
Fss = fresnel->transmission_tint;
}
microfacet_ggx_preserve_energy(kg, bsdf, sd, Fss);
}
@ -767,7 +793,8 @@ ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg,
{
/* Constant Fresnel is a special case - the color is already baked into the closure's
* weight, so we just need to perform the energy preservation. */
kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::NONE);
kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::NONE ||
bsdf->fresnel_type == MicrofacetFresnel::DIELECTRIC);
microfacet_ggx_preserve_energy(kg, bsdf, sd, color);
}

View File

@ -208,27 +208,12 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
if (sd->flag & SD_BACKFACING) {
bsdf->ior = 1.0f / bsdf->ior;
}
bsdf->T = closure->T;
/* GGX */
if (closure->distribution == make_string("ggx", 11253504724482777663ull) ||
closure->distribution == make_string("default", 4430693559278735917ull))
{
if (has_reflection && has_transmission) {
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
}
else if (has_transmission) {
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
}
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
}
bool preserve_energy = false;
/* Beckmann */
else {
if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) {
if (has_reflection && has_transmission) {
sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf);
}
@ -239,10 +224,24 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
}
}
/* GGX (either single- or multiscattering) */
else {
if (has_reflection && has_transmission) {
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
}
else if (has_transmission) {
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
}
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull));
}
fresnel->reflection_tint = rgb_to_spectrum(closure->reflection_tint);
fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint);
bsdf_microfacet_setup_fresnel_dielectric_tint(bsdf, sd, fresnel);
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, preserve_energy);
}
ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg,
@ -273,20 +272,21 @@ ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg,
bsdf->ior = 0.0f;
bsdf->T = closure->T;
/* GGX */
if (closure->distribution == make_string("ggx", 11253504724482777663ull) ||
closure->distribution == make_string("default", 4430693559278735917ull))
{
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
bool preserve_energy = false;
/* Beckmann */
else {
if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) {
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
}
/* GGX (either single- or multiscattering) */
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull));
}
fresnel->n = rgb_to_spectrum(closure->ior);
fresnel->k = rgb_to_spectrum(closure->extinction);
bsdf_microfacet_setup_fresnel_conductor(bsdf, sd, fresnel);
bsdf_microfacet_setup_fresnel_conductor(kg, bsdf, sd, fresnel, preserve_energy);
}
ccl_device void osl_closure_generalized_schlick_bsdf_setup(
@ -324,22 +324,10 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
}
bsdf->T = closure->T;
/* GGX */
if (closure->distribution == make_string("ggx", 11253504724482777663ull) ||
closure->distribution == make_string("default", 4430693559278735917ull))
{
if (has_reflection && has_transmission) {
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
}
else if (has_transmission) {
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
}
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
}
bool preserve_energy = false;
/* Beckmann */
else {
if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) {
if (has_reflection && has_transmission) {
sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf);
}
@ -350,13 +338,27 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
}
}
/* GGX (either single- or multiscattering) */
else {
if (has_reflection && has_transmission) {
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
}
else if (has_transmission) {
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
}
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull));
}
fresnel->reflection_tint = rgb_to_spectrum(closure->reflection_tint);
fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint);
fresnel->f0 = rgb_to_spectrum(closure->f0);
fresnel->f90 = rgb_to_spectrum(closure->f90);
fresnel->exponent = closure->exponent;
bsdf_microfacet_setup_fresnel_generalized_schlick(bsdf, sd, fresnel);
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
}
/* Standard microfacet closures */
@ -412,7 +414,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
else if (closure->distribution == make_string("ashikhmin_shirley", 11318482998918370922ull)) {
sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
}
/* GGX */
/* GGX (either single- or multiscattering) */
else {
if (closure->refract == 1) {
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
@ -423,195 +425,15 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
if (closure->distribution == make_string("multi_ggx", 16842698693386468366ull)) {
/* Since there's no dedicated color input, the weight is the best we got. */
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(weight));
}
}
}
ccl_device void osl_closure_microfacet_ggx_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetGGXIsotropicClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = bsdf->alpha_y = closure->alpha_x;
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
ccl_device void osl_closure_microfacet_ggx_aniso_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetGGXClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->T = closure->T;
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
}
ccl_device void osl_closure_microfacet_ggx_refraction_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetGGXRefractionClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->ior = closure->ior;
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
}
/* GGX closures with Fresnel */
ccl_device void osl_closure_microfacet_ggx_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetGGXFresnelClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)
closure_alloc_extra(sd, sizeof(FresnelPrincipledV1));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
bsdf->T = zero_float3();
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
fresnel->color = rgb_to_spectrum(closure->color);
fresnel->cspec0 = rgb_to_spectrum(closure->cspec0);
bsdf_microfacet_setup_fresnel_principledv1(bsdf, sd, fresnel);
}
ccl_device void osl_closure_microfacet_ggx_aniso_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetGGXAnisoFresnelClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)
closure_alloc_extra(sd, sizeof(FresnelPrincipledV1));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
bsdf->T = closure->T;
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
fresnel->color = rgb_to_spectrum(closure->color);
fresnel->cspec0 = rgb_to_spectrum(closure->cspec0);
bsdf_microfacet_setup_fresnel_principledv1(bsdf, sd, fresnel);
}
/* Multi-scattering GGX closures */
ccl_device void osl_closure_microfacet_multi_ggx_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXClosure *closure)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra(
sd, sizeof(FresnelConstant));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = 1.0f;
bsdf->fresnel = fresnel;
fresnel->color = rgb_to_spectrum(closure->color);
bsdf->T = zero_float3();
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
}
/* Special-purpose Microfacet closures */
ccl_device void osl_closure_microfacet_multi_ggx_glass_setup(
KernelGlobals kg,
@ -633,23 +455,15 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup(
return;
}
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra(
sd, sizeof(FresnelConstant));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
bsdf->fresnel = fresnel;
fresnel->color = rgb_to_spectrum(closure->color);
bsdf->T = zero_float3();
sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(closure->color));
}
ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
@ -657,11 +471,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXAnisoClosure *closure)
ccl_private const MicrofacetMultiGGXClosure *closure)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
@ -672,37 +483,24 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
return;
}
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra(
sd, sizeof(FresnelConstant));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = 1.0f;
bsdf->fresnel = fresnel;
fresnel->color = rgb_to_spectrum(closure->color);
bsdf->T = closure->T;
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(closure->color));
}
/* Multi-scattering GGX closures with Fresnel */
ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup(
ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXFresnelClosure *closure)
ccl_private const MicrofacetAnisoFresnelClosure *closure)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
@ -713,88 +511,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup(
return;
}
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)
closure_alloc_extra(sd, sizeof(FresnelPrincipledV1));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
bsdf->fresnel = fresnel;
fresnel->color = rgb_to_spectrum(closure->color);
fresnel->cspec0 = rgb_to_spectrum(closure->cspec0);
bsdf->T = zero_float3();
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
}
ccl_device void osl_closure_microfacet_multi_ggx_glass_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXGlassFresnelClosure *closure)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)
closure_alloc_extra(sd, sizeof(FresnelPrincipledV1));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
bsdf->fresnel = fresnel;
fresnel->color = rgb_to_spectrum(closure->color);
fresnel->cspec0 = rgb_to_spectrum(closure->cspec0);
bsdf->T = zero_float3();
sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
}
ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXAnisoFresnelClosure *closure)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
* is probably as good as it gets. */
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)
closure_alloc_extra(sd, sizeof(FresnelPrincipledV1));
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
closure_alloc_extra(sd, sizeof(FresnelGeneralizedSchlick));
if (!fresnel) {
return;
}
@ -803,91 +521,23 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup(
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
bsdf->fresnel = fresnel;
fresnel->color = rgb_to_spectrum(closure->color);
fresnel->cspec0 = rgb_to_spectrum(closure->cspec0);
bsdf->T = closure->T;
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
/* Only GGX (either single- or multiscattering) supported here */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
const bool preserve_energy = (closure->distribution ==
make_string("multi_ggx", 16842698693386468366ull));
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = zero_spectrum();
fresnel->f0 = rgb_to_spectrum(closure->f0);
fresnel->f90 = rgb_to_spectrum(closure->f90);
fresnel->exponent = -1.0f;
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
}
/* Beckmann closures */
ccl_device void osl_closure_microfacet_beckmann_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetBeckmannIsotropicClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = bsdf->alpha_y = closure->alpha_x;
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
}
ccl_device void osl_closure_microfacet_beckmann_aniso_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetBeckmannClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->T = closure->T;
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
}
ccl_device void osl_closure_microfacet_beckmann_refraction_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetBeckmannRefractionClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->ior = closure->ior;
sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
}
/* Ashikhmin closures */
/* Ashikhmin Velvet */
ccl_device void osl_closure_ashikhmin_velvet_setup(
KernelGlobals kg,
@ -912,31 +562,6 @@ ccl_device void osl_closure_ashikhmin_velvet_setup(
sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
}
ccl_device void osl_closure_ashikhmin_shirley_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const AshikhminShirleyClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->T = closure->T;
sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
}
ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,

View File

@ -83,30 +83,6 @@ OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet)
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL)
OSL_CLOSURE_STRUCT_END(Microfacet, microfacet)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXIsotropic, microfacet_ggx)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetGGXIsotropic, microfacet_ggx)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGX, microfacet_ggx_aniso)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetGGX, microfacet_ggx_aniso)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, alpha_x, NULL)
@ -114,82 +90,24 @@ OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx_aniso)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx_aniso)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXFresnel, microfacet_ggx_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, cspec0, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetGGXFresnel, microfacet_ggx_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, cspec0, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, cspec0, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannIsotropic, microfacet_beckmann)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannIsotropic, microfacet_beckmann)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmann, microfacet_beckmann_aniso)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmann, microfacet_beckmann_aniso)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
OSL_CLOSURE_STRUCT_BEGIN(AshikhminShirley, ashikhmin_shirley)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_END(AshikhminShirley, ashikhmin_shirley)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetAnisoFresnel, microfacet_aniso_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, f0, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, f90, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, STRING, DeviceString, distribution, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetAnisoFresnel, microfacet_aniso_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL)

View File

@ -36,3 +36,9 @@ color fresnel_conductor(float cosi, color eta, color k)
color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) / (tmp_f + (2.0 * eta * cosi) + cosi2);
return (Rparl2 + Rperp2) * 0.5;
}
float F0_from_ior(float eta)
{
float f0 = (eta - 1.0) / (eta + 1.0);
return f0 * f0;
}

View File

@ -40,7 +40,7 @@ shader node_glossy_bsdf(color Color = 0.8,
}
if (distribution == "Multiscatter GGX")
BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color);
BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
else
BSDF = Color * microfacet(distribution, Normal, T, roughness_u, roughness_v, 0.0, 0);
}

View File

@ -4,7 +4,7 @@
#include "node_fresnel.h"
#include "stdcycles.h"
shader node_principled_bsdf(string distribution = "Multiscatter GGX",
shader node_principled_bsdf(string distribution = "multi_ggx",
string subsurface_method = "random_walk",
color BaseColor = color(0.8, 0.8, 0.8),
float Subsurface = 0.0,
@ -34,6 +34,7 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX",
float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
float specular_weight = (1.0 - final_transmission);
float r2 = Roughness * Roughness;
vector T = Tangent;
@ -65,52 +66,35 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX",
}
if (Sheen > 1e-5) {
color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
color sheen_color = mix(color(1.0), m_ctint, SheenTint);
BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal);
BSDF += sheen_color * Sheen * principled_sheen(Normal);
}
BSDF = BSDF * diffuse_weight;
BSDF *= diffuse_weight;
}
if (specular_weight > 1e-5) {
float aspect = sqrt(1.0 - Anisotropic * 0.9);
float r2 = Roughness * Roughness;
float alpha_x = r2 / aspect;
float alpha_y = r2 * aspect;
color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint;
color tmp_col = mix(color(1.0), m_ctint, SpecularTint);
color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
if (distribution == "GGX" || Roughness <= 0.075) {
BSDF = BSDF + specular_weight *
microfacet_ggx_aniso_fresnel(Normal,
T,
alpha_x,
alpha_y,
(2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
BaseColor,
Cspec0);
}
else {
BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(
Normal,
T,
alpha_x,
alpha_y,
(2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
BaseColor,
Cspec0);
}
float eta = (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0;
string spec_dist = (Roughness <= 0.075) ? "ggx" : distribution;
BSDF += specular_weight * microfacet_aniso_fresnel(
Normal, T, alpha_x, alpha_y, Cspec0, color(1.0), eta, spec_dist);
}
if (final_transmission > 1e-5) {
color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
color Cspec0 = mix(color(1.0), BaseColor, SpecularTint);
float eta = backfacing() ? 1.0 / f : f;
if (distribution == "GGX" || Roughness <= 5e-2) {
if (distribution == "ggx" || Roughness <= 5e-2) {
float cosNI = dot(Normal, I);
float Fr = fresnel_dielectric_cos(cosNI, eta);
@ -119,26 +103,23 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX",
refl_roughness = 0.0;
float transmission_roughness = refl_roughness;
if (distribution == "GGX")
if (distribution == "ggx")
transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness);
BSDF = BSDF +
final_transmission *
(Fr * microfacet_ggx_fresnel(
Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
(1.0 - Fr) * BaseColor *
microfacet_ggx_refraction(
Normal, transmission_roughness * transmission_roughness, eta));
closure color refraction = microfacet(
"ggx", Normal, transmission_roughness * transmission_roughness, eta, 1);
closure color reflection = microfacet_aniso_fresnel(
Normal, T, r2, r2, Cspec0, color(1.0), eta, "ggx");
BSDF += final_transmission * mix(BaseColor * refraction, reflection, Fr);
}
else {
BSDF = BSDF +
final_transmission * microfacet_multi_ggx_glass_fresnel(
Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
BSDF += final_transmission *
dielectric_bsdf(Normal, vector(0.0), Cspec0, BaseColor, r2, r2, eta, "multi_ggx");
}
}
if (Clearcoat > 1e-5) {
BSDF = BSDF + principled_clearcoat(
ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
BSDF += principled_clearcoat(
ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
}
}

View File

@ -20,31 +20,21 @@ closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
closure color glossy_toon(normal N, float size, float smooth) BUILTIN;
closure color microfacet_ggx(normal N, float ag) BUILTIN;
closure color microfacet_ggx_aniso(normal N, vector T, float ax, float ay) BUILTIN;
closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
closure color microfacet_multi_ggx(normal N, float ag, color C) BUILTIN;
closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
closure color microfacet_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
closure color microfacet_ggx_aniso_fresnel(
normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
closure color
microfacet_multi_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
closure color microfacet_multi_ggx_aniso_fresnel(
normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
closure color
microfacet_multi_ggx_glass_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
closure color microfacet_beckmann(normal N, float ab) BUILTIN;
closure color microfacet_beckmann_aniso(normal N, vector T, float ax, float ay) BUILTIN;
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
closure color ashikhmin_shirley(normal N, vector T, float ax, float ay) BUILTIN;
closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color ambient_occlusion() BUILTIN;
closure color principled_diffuse(normal N, float roughness) BUILTIN;
closure color principled_sheen(normal N) BUILTIN;
closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN;
/* Needed to pass along the color for multiscattering saturation adjustment,
* otherwise could be replaced by microfacet() */
closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
/* Needed to pass along the IOR for the Principled V1 Fresnel calculation,
* otherwise could be replaced by generalized_schlick_bsdf() */
closure color microfacet_aniso_fresnel(
normal N, vector T, float ax, float ay, color f0, color f90, float eta, string dist) BUILTIN;
// BSSRDF
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN;

View File

@ -2750,7 +2750,7 @@ NODE_DEFINE(PrincipledBsdfNode)
NodeType *type = NodeType::add("principled_bsdf", create, NodeType::SHADER);
static NodeEnum distribution_enum;
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
SOCKET_ENUM(
distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);