[Bf-blender-cvs] [cef4d344f94] master: Fix Embree failing on objects with a very high number of motion steps

Brecht Van Lommel noreply at git.blender.org
Tue Feb 18 15:39:55 CET 2020


Commit: cef4d344f948ce75a7787ad0c3915c87e1716ca1
Author: Brecht Van Lommel
Date:   Tue Feb 18 14:02:40 2020 +0100
Branches: master
https://developer.blender.org/rBcef4d344f948ce75a7787ad0c3915c87e1716ca1

Fix Embree failing on objects with a very high number of motion steps

Set the limit to 129 to match Embree. This applies to all devices for
consistent render results.

Ref T73778

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

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_util.h
M	intern/cycles/bvh/bvh_embree.cpp
M	intern/cycles/render/geometry.h
M	intern/cycles/render/object.h

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

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index eafe37618b3..23ff1771995 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1132,7 +1132,7 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
     motion_steps: IntProperty(
         name="Motion Steps",
         description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
-        min=1, soft_max=8,
+        min=1, max=7,
         default=1,
     )
 
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 2b1d1eff7e5..334c25cafe1 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -266,7 +266,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
       uint motion_steps;
 
       if (need_motion == Scene::MOTION_BLUR) {
-        motion_steps = object_motion_steps(b_parent, b_ob);
+        motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS);
         geom->motion_steps = motion_steps;
         if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
           geom->use_motion_blur = true;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index cb7d1c62f60..ad90a5f8d52 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -483,7 +483,9 @@ static inline void mesh_texture_space(BL::Mesh &b_mesh, float3 &loc, float3 &siz
 }
 
 /* Object motion steps, returns 0 if no motion blur needed. */
-static inline uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob)
+static inline uint object_motion_steps(BL::Object &b_parent,
+                                       BL::Object &b_ob,
+                                       const int max_steps = INT_MAX)
 {
   /* Get motion enabled and steps from object itself. */
   PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
@@ -492,7 +494,7 @@ static inline uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob)
     return 0;
   }
 
-  uint steps = max(1, get_int(cobject, "motion_steps"));
+  int steps = max(1, get_int(cobject, "motion_steps"));
 
   /* Also check parent object, so motion blur and steps can be
    * controlled by dupligroup duplicator for linked groups. */
@@ -510,7 +512,7 @@ static inline uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob)
   /* Use uneven number of steps so we get one keyframe at the current frame,
    * and use 2^(steps - 1) so objects with more/fewer steps still have samples
    * at the same times, to avoid sampling at many different times. */
-  return (2 << (steps - 1)) + 1;
+  return min((2 << (steps - 1)) + 1, max_steps);
 }
 
 /* object uses deformation motion blur */
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 2d3cc622891..84b00aab91c 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -58,6 +58,11 @@
 
 CCL_NAMESPACE_BEGIN
 
+static_assert(Object::MAX_MOTION_STEPS <= RTC_MAX_TIME_STEP_COUNT,
+              "Object and Embree max motion steps inconsistent");
+static_assert(Object::MAX_MOTION_STEPS == Geometry::MAX_MOTION_STEPS,
+              "Object and Geometry max motion steps inconsistent");
+
 #  define IS_HAIR(x) (x & 1)
 
 /* This gets called by Embree at every valid ray/object intersection.
@@ -557,7 +562,10 @@ void BVHEmbree::add_instance(Object *ob, int i)
     instance_bvh->top_level = this;
   }
 
-  const size_t num_motion_steps = ob->use_motion() ? ob->motion.size() : 1;
+  const size_t num_object_motion_steps = ob->use_motion() ? ob->motion.size() : 1;
+  const size_t num_motion_steps = min(num_object_motion_steps, RTC_MAX_TIME_STEP_COUNT);
+  assert(num_object_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
+
   RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_INSTANCE);
   rtcSetGeometryInstancedScene(geom_id, instance_bvh->scene);
   rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
@@ -600,18 +608,17 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
 {
   size_t prim_offset = pack.prim_index.size();
   const Attribute *attr_mP = NULL;
-  size_t num_motion_steps = 1;
+  size_t num_geometry_motion_steps = 1;
   if (mesh->has_motion_blur()) {
     attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
     if (attr_mP) {
-      num_motion_steps = mesh->motion_steps;
-      if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
-        assert(0);
-        num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
-      }
+      num_geometry_motion_steps = mesh->motion_steps;
     }
   }
 
+  const size_t num_motion_steps = min(num_geometry_motion_steps, RTC_MAX_TIME_STEP_COUNT);
+  assert(num_geometry_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
+
   const size_t num_triangles = mesh->num_triangles();
   RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_TRIANGLE);
   rtcSetGeometryBuildQuality(geom_id, build_quality);
@@ -782,14 +789,17 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
 {
   size_t prim_offset = pack.prim_index.size();
   const Attribute *attr_mP = NULL;
-  size_t num_motion_steps = 1;
+  size_t num_geometry_motion_steps = 1;
   if (hair->has_motion_blur()) {
     attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
     if (attr_mP) {
-      num_motion_steps = hair->motion_steps;
+      num_geometry_motion_steps = hair->motion_steps;
     }
   }
 
+  const size_t num_motion_steps = min(num_geometry_motion_steps, RTC_MAX_TIME_STEP_COUNT);
+  assert(num_geometry_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
+
   const size_t num_curves = hair->num_curves();
   size_t num_segments = 0;
   for (size_t j = 0; j < num_curves; ++j) {
diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h
index 711da1c81e8..66ae8472102 100644
--- a/intern/cycles/render/geometry.h
+++ b/intern/cycles/render/geometry.h
@@ -72,6 +72,9 @@ class Geometry : public Node {
   uint motion_steps;
   bool use_motion_blur;
 
+  /* Maximum number of motion steps supported (due to Embree). */
+  static const uint MAX_MOTION_STEPS = 129;
+
   /* BVH */
   BVH *bvh;
   size_t attr_map_offset;
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index c5d878ec938..7bd3edf769b 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -81,6 +81,9 @@ class Object : public Node {
   int motion_step(float time) const;
   void update_motion();
 
+  /* Maximum number of motion steps supported (due to Embree). */
+  static const uint MAX_MOTION_STEPS = 129;
+
   /* Check whether object is traceable and it worth adding it to
    * kernel scene.
    */



More information about the Bf-blender-cvs mailing list