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
This commit is contained in:
@@ -1132,7 +1132,7 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
|
|||||||
motion_steps: IntProperty(
|
motion_steps: IntProperty(
|
||||||
name="Motion Steps",
|
name="Motion Steps",
|
||||||
description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
|
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,
|
default=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -266,7 +266,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
|
|||||||
uint motion_steps;
|
uint motion_steps;
|
||||||
|
|
||||||
if (need_motion == Scene::MOTION_BLUR) {
|
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;
|
geom->motion_steps = motion_steps;
|
||||||
if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
|
if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
|
||||||
geom->use_motion_blur = true;
|
geom->use_motion_blur = true;
|
||||||
|
@@ -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. */
|
/* 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. */
|
/* Get motion enabled and steps from object itself. */
|
||||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
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;
|
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
|
/* Also check parent object, so motion blur and steps can be
|
||||||
* controlled by dupligroup duplicator for linked groups. */
|
* 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,
|
/* 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
|
* 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. */
|
* 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 */
|
/* object uses deformation motion blur */
|
||||||
|
@@ -58,6 +58,11 @@
|
|||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
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)
|
# define IS_HAIR(x) (x & 1)
|
||||||
|
|
||||||
/* This gets called by Embree at every valid ray/object intersection.
|
/* 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;
|
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);
|
RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_INSTANCE);
|
||||||
rtcSetGeometryInstancedScene(geom_id, instance_bvh->scene);
|
rtcSetGeometryInstancedScene(geom_id, instance_bvh->scene);
|
||||||
rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
|
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();
|
size_t prim_offset = pack.prim_index.size();
|
||||||
const Attribute *attr_mP = NULL;
|
const Attribute *attr_mP = NULL;
|
||||||
size_t num_motion_steps = 1;
|
size_t num_geometry_motion_steps = 1;
|
||||||
if (mesh->has_motion_blur()) {
|
if (mesh->has_motion_blur()) {
|
||||||
attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if (attr_mP) {
|
if (attr_mP) {
|
||||||
num_motion_steps = mesh->motion_steps;
|
num_geometry_motion_steps = mesh->motion_steps;
|
||||||
if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
|
|
||||||
assert(0);
|
|
||||||
num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
const size_t num_triangles = mesh->num_triangles();
|
||||||
RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_TRIANGLE);
|
RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, RTC_GEOMETRY_TYPE_TRIANGLE);
|
||||||
rtcSetGeometryBuildQuality(geom_id, build_quality);
|
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();
|
size_t prim_offset = pack.prim_index.size();
|
||||||
const Attribute *attr_mP = NULL;
|
const Attribute *attr_mP = NULL;
|
||||||
size_t num_motion_steps = 1;
|
size_t num_geometry_motion_steps = 1;
|
||||||
if (hair->has_motion_blur()) {
|
if (hair->has_motion_blur()) {
|
||||||
attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if (attr_mP) {
|
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();
|
const size_t num_curves = hair->num_curves();
|
||||||
size_t num_segments = 0;
|
size_t num_segments = 0;
|
||||||
for (size_t j = 0; j < num_curves; ++j) {
|
for (size_t j = 0; j < num_curves; ++j) {
|
||||||
|
@@ -72,6 +72,9 @@ class Geometry : public Node {
|
|||||||
uint motion_steps;
|
uint motion_steps;
|
||||||
bool use_motion_blur;
|
bool use_motion_blur;
|
||||||
|
|
||||||
|
/* Maximum number of motion steps supported (due to Embree). */
|
||||||
|
static const uint MAX_MOTION_STEPS = 129;
|
||||||
|
|
||||||
/* BVH */
|
/* BVH */
|
||||||
BVH *bvh;
|
BVH *bvh;
|
||||||
size_t attr_map_offset;
|
size_t attr_map_offset;
|
||||||
|
@@ -81,6 +81,9 @@ class Object : public Node {
|
|||||||
int motion_step(float time) const;
|
int motion_step(float time) const;
|
||||||
void update_motion();
|
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
|
/* Check whether object is traceable and it worth adding it to
|
||||||
* kernel scene.
|
* kernel scene.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user