[Bf-blender-cvs] [db333d9ea48] master: Cycles: support arbitrary number of motion blur steps for objects.

Brecht Van Lommel noreply at git.blender.org
Sat Mar 10 06:44:05 CET 2018


Commit: db333d9ea4881d9f48e3cc4b1ec59b4dafb27cc0
Author: Brecht Van Lommel
Date:   Thu Mar 8 04:04:52 2018 +0100
Branches: master
https://developer.blender.org/rBdb333d9ea4881d9f48e3cc4b1ec59b4dafb27cc0

Cycles: support arbitrary number of motion blur steps for objects.

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

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/blender_camera.cpp
M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_util.h
M	intern/cycles/kernel/geom/geom_object.h
M	intern/cycles/kernel/kernel_light.h
M	intern/cycles/kernel/kernel_textures.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/object.cpp
M	intern/cycles/render/object.h
M	intern/cycles/render/scene.cpp
M	intern/cycles/render/scene.h
M	intern/cycles/render/session.cpp
M	intern/cycles/util/util_transform.h

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

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 62aea8790af..1b95c365616 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1088,7 +1088,7 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
 
         cls.motion_steps = IntProperty(
                 name="Motion Steps",
-                description="Control accuracy of deformation 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,
                 default=1,
                 )
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 909db8d9449..f00ade320e7 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -229,9 +229,7 @@ static void blender_camera_from_object(BlenderCamera *bcam,
 		else
 			bcam->sensor_fit = BlenderCamera::VERTICAL;
 
-		if(object_use_motion(b_ob, b_ob)) {
-			bcam->motion_steps = object_motion_steps(b_ob);
-		}
+		bcam->motion_steps = object_motion_steps(b_ob, b_ob);
 	}
 	else {
 		/* from lamp not implemented yet */
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 45309292f0b..4b40f4d458b 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -327,22 +327,11 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 	if(motion) {
 		object = object_map.find(key);
 
-		if(object && (scene->need_motion() == Scene::MOTION_PASS ||
-		              object_use_motion(b_parent, b_ob)))
-		{
-			/* object transformation */
-			if(tfm != object->tfm) {
-				VLOG(1) << "Object " << b_ob.name() << " motion detected.";
-				if(motion_time == -1.0f || motion_time == 1.0f) {
-					object->use_motion = true;
-				}
-			}
-
-			if(motion_time == -1.0f) {
-				object->motion.pre = tfm;
-			}
-			else if(motion_time == 1.0f) {
-				object->motion.post = tfm;
+		if(object && object->use_motion()) {
+			/* Set transform at matching motion time step. */
+			int time_index = object->motion_step(motion_time);
+			if(time_index >= 0) {
+				object->motion[time_index] = tfm;
 			}
 
 			/* mesh deformation */
@@ -389,24 +378,34 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 		object->name = b_ob.name().c_str();
 		object->pass_id = b_ob.pass_index();
 		object->tfm = tfm;
-		object->motion.pre = transform_empty();
-		object->motion.post = transform_empty();
-		object->use_motion = false;
+		object->motion.clear();
 
 		/* motion blur */
-		if(scene->need_motion() == Scene::MOTION_BLUR && object->mesh) {
+		Scene::MotionType need_motion = scene->need_motion();
+		if(need_motion != Scene::MOTION_NONE && object->mesh) {
 			Mesh *mesh = object->mesh;
 			mesh->use_motion_blur = false;
+			mesh->motion_steps = 0;
 
-			if(object_use_motion(b_parent, b_ob)) {
+			uint motion_steps;
+
+			if(scene->need_motion() == Scene::MOTION_BLUR) {
+				motion_steps = object_motion_steps(b_parent, b_ob);
 				if(object_use_deform_motion(b_parent, b_ob)) {
-					mesh->motion_steps = object_motion_steps(b_ob);
+					mesh->motion_steps = motion_steps;
 					mesh->use_motion_blur = true;
 				}
+			}
+			else {
+				motion_steps = 3;
+				mesh->motion_steps = motion_steps;
+			}
 
-				for(size_t step = 0; step < mesh->motion_steps - 1; step++) {
-					motion_times.insert(mesh->motion_time(step));
-				}
+			object->motion.resize(motion_steps, transform_empty());
+			object->motion[motion_steps/2] = tfm;
+
+			for(size_t step = 0; step < motion_steps; step++) {
+				motion_times.insert(object->motion_time(step));
 			}
 		}
 
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index c4c45035b5a..c418b19a637 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -484,33 +484,34 @@ static inline void mesh_texture_space(BL::Mesh& b_mesh,
 	loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
 }
 
-/* object used for motion blur */
-static inline bool object_use_motion(BL::Object& b_parent, BL::Object& b_ob)
+/* Object motion steps, returns 0 if no motion blur needed. */
+static inline uint object_motion_steps(BL::Object& b_parent, BL::Object& b_ob)
 {
+	/* Get motion enabled and steps from object itself. */
 	PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
 	bool use_motion = get_boolean(cobject, "use_motion_blur");
-	/* If motion blur is enabled for the object we also check
-	 * whether it's enabled for the parent object as well.
-	 *
-	 * This way we can control motion blur from the dupligroup
-	 * duplicator much easier.
-	 */
-	if(use_motion && b_parent.ptr.data != b_ob.ptr.data) {
+	if(!use_motion) {
+		return 0;
+	}
+
+	uint 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. */
+	if(b_parent.ptr.data != b_ob.ptr.data) {
 		PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
 		use_motion &= get_boolean(parent_cobject, "use_motion_blur");
-	}
-	return use_motion;
-}
 
-/* object motion steps */
-static inline uint object_motion_steps(BL::Object& b_ob)
-{
-	PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
-	uint steps = get_int(cobject, "motion_steps");
+		if(!use_motion) {
+			return 0;
+		}
+
+		steps = max(steps, get_int(parent_cobject, "motion_steps"));
+	}
 
-	/* use uneven number of steps so we get one keyframe at the current frame,
-	 * and ue 2^(steps - 1) so objects with more/fewer steps still have samples
-	 * at the same times, to avoid sampling at many different times */
+	/* 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;
 }
 
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 67d039e1bc7..800649abf38 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -40,18 +40,12 @@ enum ObjectVectorTransform {
 
 ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
 {
-	Transform tfm;
 	if(type == OBJECT_INVERSE_TRANSFORM) {
-		tfm.x = kernel_tex_fetch(__objects, object).tfm.mid.x;
-		tfm.y = kernel_tex_fetch(__objects, object).tfm.mid.y;
-		tfm.z = kernel_tex_fetch(__objects, object).tfm.mid.z;
+		return kernel_tex_fetch(__objects, object).itfm;
 	}
 	else {
-		tfm.x = kernel_tex_fetch(__objects, object).tfm.pre.x;
-		tfm.y = kernel_tex_fetch(__objects, object).tfm.pre.y;
-		tfm.z = kernel_tex_fetch(__objects, object).tfm.pre.z;
+		return kernel_tex_fetch(__objects, object).tfm;
 	}
-	return tfm;
 }
 
 /* Lamp to world space transformation */
@@ -79,10 +73,12 @@ ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals *kg
 #ifdef __OBJECT_MOTION__
 ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
 {
-	const ccl_global DecomposedMotionTransform *motion = &kernel_tex_fetch(__objects, object).tfm;
+	const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset;
+	const ccl_global DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset);
+	const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1;
 
 	Transform tfm;
-	transform_motion_array_interpolate(&tfm, &motion->pre, 3, time);
+	transform_motion_array_interpolate(&tfm, motion, num_steps, time);
 
 	return tfm;
 }
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index aaf7a7abdd4..efab69ee37d 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -792,7 +792,8 @@ ccl_device_inline bool triangle_world_space_vertices(KernelGlobals *kg, int obje
 #ifdef __INSTANCING__
 	if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
 #  ifdef __OBJECT_MOTION__
-		Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
+		float object_time = (time >= 0.0f) ? time : 0.5f;
+		Transform tfm = object_fetch_transform_motion_test(kg, object, object_time, NULL);
 #  else
 		Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
 #  endif
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 56de5b27605..9047b93a0b2 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -33,6 +33,7 @@ KERNEL_TEX(float2, __prim_time)
 /* objects */
 KERNEL_TEX(KernelObject, __objects)
 KERNEL_TEX(Transform, __object_motion_pass)
+KERNEL_TEX(DecomposedTransform, __object_motion)
 KERNEL_TEX(uint, __object_flag)
 
 /* cameras */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 2c3b7ba29a4..977ceac12ea 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1433,7 +1433,8 @@ static_assert_align(KernelData, 16);
 /* Kernel data structures. */
 
 typedef struct KernelObject {
-	DecomposedMotionTransform tfm;
+	Transform tfm;
+	Transform itfm;
 
 	float surface_area;
 	float pass_id;
@@ -1449,7 +1450,8 @@ typedef struct KernelObject {
 
 	uint patch_map_offset;
 	uint attribute_map_offset;
-	uint pad1, pad2;
+	uint motion_offset;
+	uint pad;
 } KernelObject;;
 static_assert_align(KernelObject, 16);
 
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index bde340ae928..138de250c5f 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -54,6 +54,9 @@ struct UpdateObjectTransformState {
 	 */
 	map<Mesh*, float> surface_area_map;
 
+	/* Motion offsets for each object. */
+	array<uint> motion_offset;
+
 	/* Packed object arrays. Those will be filled in. */
 	uint *object_flag;
 	KernelObject *objects;
@@ -91,6 +94,7 @@ NODE_D

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list