[Bf-blender-cvs] [c7280ce65b8] master: Cycles: Added shadow terminator offset parameter.

Stefan Werner noreply at git.blender.org
Tue Jun 2 07:27:56 CEST 2020


Commit: c7280ce65b856d26d6807c1b7a081ffc6311bfdc
Author: Stefan Werner
Date:   Tue May 5 13:55:24 2020 +0200
Branches: master
https://developer.blender.org/rBc7280ce65b856d26d6807c1b7a081ffc6311bfdc

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

===================================================================

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/kernel/closure/bsdf.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/object.cpp
M	intern/cycles/render/object.h

===================================================================

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;



More information about the Bf-blender-cvs mailing list