diff options
author | Stefan Werner <stefan.werner@tangent-animation.com> | 2020-05-05 14:55:24 +0300 |
---|---|---|
committer | Stefan Werner <stefan.werner@tangent-animation.com> | 2020-06-02 08:27:14 +0300 |
commit | c7280ce65b856d26d6807c1b7a081ffc6311bfdc (patch) | |
tree | f1dc9453d24b0352cc87cf45bf7b5848da86d6d4 /intern/cycles/kernel | |
parent | 18cda8be8768b1e4ad9c359295142272e7aac6bf (diff) |
Cycles: Added shadow terminator offset parameter.
A new user parameter can be used to shift the shadow terminator
towards the light source. With it, one can hide some of the
artifacts that appear on coarse meshes with smooth shading.
Note that this technique is not engery conserving.
This is based on the work by the Appleseed renderer team.
Differential Revision: https://developer.blender.org/D7634
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 30 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 3 |
2 files changed, 30 insertions, 3 deletions
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index dc80e67a891..a70a6bfbba1 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,16 @@ 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 +580,11 @@ 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) { diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 304835a1685..630d00a4e71 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1480,6 +1480,9 @@ typedef struct KernelObject { float cryptomatte_object; float cryptomatte_asset; + + float shadow_terminator_offset; + float pad1, pad2, pad3; } KernelObject; static_assert_align(KernelObject, 16); |