diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 7 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 22 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 30 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 1 |
7 files changed, 68 insertions, 3 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index c91e210bbd8..da18ac7c693 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1205,6 +1205,13 @@ class CyclesObjectSettings(bpy.types.PropertyGroup): default=1.0, ) + shadow_terminator_offset: FloatProperty( + name="Shadow Terminator Offset", + description="Push the shadow terminator towards the light to hide artifacts on low poly geometry", + min=0.0, max=1.0, + default=0.0, + ) + is_shadow_catcher: BoolProperty( name="Shadow Catcher", description="Only render shadows on this object, for compositing renders into real footage", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index a15daee706f..7a339e71197 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1209,6 +1209,27 @@ def has_geometry_visibility(ob): return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or (ob.instance_type == 'COLLECTION' and ob.instance_collection)) +class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel): + bl_label = "Shading" + bl_context = "object" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return CyclesButtonsPanel.poll(context) and (context.object) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + layout = self.layout + ob = context.object + cob = ob.cycles + + if has_geometry_visibility(ob): + col = flow.column() + col.prop(cob, "shadow_terminator_offset") class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel): bl_label = "Visibility" @@ -2268,6 +2289,7 @@ classes = ( CYCLES_CAMERA_PT_dof_aperture, CYCLES_PT_context_material, CYCLES_OBJECT_PT_motion_blur, + CYCLES_OBJECT_PT_shading, CYCLES_OBJECT_PT_visibility, CYCLES_OBJECT_PT_visibility_ray_visibility, CYCLES_OBJECT_PT_visibility_culling, diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index a461982a538..c28586d0f63 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -238,6 +238,12 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, object_updated = true; } + float shadow_terminator_offset = get_float(cobject, "shadow_terminator_offset"); + if (shadow_terminator_offset != object->shadow_terminator_offset) { + object->shadow_terminator_offset = shadow_terminator_offset; + object_updated = true; + } + /* sync the asset name for Cryptomatte */ BL::Object parent = b_ob.parent(); ustring parent_name; 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); diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 90a1d90019d..61deef4cd76 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -101,6 +101,7 @@ NODE_DEFINE(Object) SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f)); SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>()); + SOCKET_FLOAT(shadow_terminator_offset, "Terminator Offset", 0.0f); SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false); @@ -534,6 +535,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0); kobject.cryptomatte_object = util_hash_to_float(hash_name); kobject.cryptomatte_asset = util_hash_to_float(hash_asset); + kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset); /* Object flag. */ if (ob->use_holdout) { diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 7c84c2de4fb..ac9b4c331f5 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -59,6 +59,7 @@ class Object : public Node { bool hide_on_missing_motion; bool use_holdout; bool is_shadow_catcher; + float shadow_terminator_offset; float3 dupli_generated; float2 dupli_uv; |