diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index dc80e67a891..4cc61e8ee71 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -97,6 +97,18 @@ ccl_device_inline float bump_shadowing_term(float3 Ng, float3 N, float3 I) return -g2 * g + g2 + g; } +/* Shadow terminator workaround, taken from Appleseed. + * Original code is under the MIT License + * Copyright (c) 2019 Francois Beaune, The appleseedhq Organization */ +ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multiplier) +{ + cos_in = min(cos_in, 1.0f); + + const float angle = fast_acosf(cos_in); + const float val = max(cosf(angle * frequency_multiplier), 0.0f) / cos_in; + return val; +} + ccl_device_inline int bsdf_sample(KernelGlobals *kg, ShaderData *sd, const ShaderClosure *sc, @@ -444,9 +456,17 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg, } } } - else if (label & LABEL_DIFFUSE) { - if (!isequal_float3(sc->N, sd->N)) { - *eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in); + else { + /* Shadow terminator offset. */ + const float frequency_multiplier = + kernel_tex_fetch(__objects, sd->object).shadow_terminator_offset; + if (frequency_multiplier > 1.0f) { + *eval *= shift_cos_in(dot(*omega_in, sc->N), frequency_multiplier); + } + if (label & LABEL_DIFFUSE) { + if (!isequal_float3(sc->N, sd->N)) { + *eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in); + } } } @@ -561,6 +581,12 @@ ccl_device_inline eval *= bump_shadowing_term(sd->N, sc->N, omega_in); } } + /* Shadow terminator offset. */ + const float frequency_multiplier = + kernel_tex_fetch(__objects, sd->object).shadow_terminator_offset; + if (frequency_multiplier > 1.0f) { + eval *= shift_cos_in(dot(omega_in, sc->N), frequency_multiplier); + } } else { switch (sc->type) { |