Cycles: Remove MultiGGX code, replace with albedo scaling #107958
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue