Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/addon/properties.py7
-rw-r--r--intern/cycles/blender/addon/ui.py22
-rw-r--r--intern/cycles/blender/blender_object.cpp6
-rw-r--r--intern/cycles/kernel/closure/bsdf.h30
-rw-r--r--intern/cycles/kernel/kernel_types.h3
-rw-r--r--intern/cycles/render/object.cpp2
-rw-r--r--intern/cycles/render/object.h1
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;