[Bf-blender-cvs] [6020d00] master: Cycles: add support for mesh deformation motion blur.

Brecht Van Lommel noreply at git.blender.org
Sat Mar 29 15:33:03 CET 2014


Commit: 6020d0099039ed18c6a6cd330b68361123c85c1a
Author: Brecht Van Lommel
Date:   Sat Mar 29 13:03:47 2014 +0100
https://developer.blender.org/rB6020d0099039ed18c6a6cd330b68361123c85c1a

Cycles: add support for mesh deformation motion blur.

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/bvh/bvh.cpp
M	intern/cycles/bvh/bvh_build.cpp
M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/geom/geom_bvh.h
M	intern/cycles/kernel/geom/geom_bvh_subsurface.h
M	intern/cycles/kernel/geom/geom_bvh_traversal.h
A	intern/cycles/kernel/geom/geom_motion_triangle.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/osl/osl_services.cpp
M	intern/cycles/kernel/svm/svm_wireframe.h
M	intern/cycles/render/light.cpp
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/object.cpp
M	intern/cycles/util/util_math.h

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index ed19fb2..8c97342 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -559,6 +559,9 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
 	int time_index = 0;
 
 	if(scene->need_motion() == Scene::MOTION_BLUR) {
+		if(!mesh->use_motion_blur)
+			return;
+		
 		/* see if this mesh needs motion data at this time */
 		vector<float> object_times = object->motion_times();
 		bool found = false;
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index f5945a6..bd4becb 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -324,8 +324,10 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
 			Mesh *mesh = object->mesh;
 
 			if(true) {
-				if(true)
+				if(true) {
 					mesh->motion_steps = 3;
+					mesh->use_motion_blur = true;
+				}
 
 				vector<float> times = object->motion_times();
 				foreach(float time, times)
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index c0d70e0..92ad3cd 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -241,6 +241,10 @@ void BVH::pack_triangle(int idx, float4 woop[3])
 	/* create Woop triangle */
 	int tob = pack.prim_object[idx];
 	const Mesh *mesh = objects[tob]->mesh;
+
+	if(mesh->has_motion_blur())
+		return;
+
 	int tidx = pack.prim_index[idx];
 	const int *vidx = mesh->triangles[tidx].v;
 	const float3* vpos = &mesh->verts[0];
@@ -646,6 +650,20 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
 					const float3 *vpos = &mesh->verts[0];
 
 					triangle.bounds_grow(vpos, bbox);
+
+					/* motion triangles */
+					if(mesh->use_motion_blur) {
+						Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+						if(attr) {
+							size_t mesh_size = mesh->verts.size();
+							size_t steps = mesh->motion_steps - 1;
+							float3 *vert_steps = attr->data_float3();
+
+							for (size_t i = 0; i < steps; i++)
+								triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
+						}
+					}
 				}
 			}
 
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index ef48c1e..f52626d 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -70,6 +70,11 @@ BVHBuild::~BVHBuild()
 
 void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
 {
+	Attribute *attr_mP = NULL;
+	
+	if(mesh->has_motion_blur())
+		attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
 	for(uint j = 0; j < mesh->triangles.size(); j++) {
 		Mesh::Triangle t = mesh->triangles[j];
 		BoundBox bounds = BoundBox::empty;
@@ -77,6 +82,18 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
 
 		t.bounds_grow(&mesh->verts[0], bounds);
 
+		/* motion triangles */
+		if(attr_mP) {
+			size_t mesh_size = mesh->verts.size();
+			size_t steps = mesh->motion_steps - 1;
+			float3 *vert_steps = attr_mP->data_float3();
+
+			for(size_t i = 0; i < steps; i++)
+				t.bounds_grow(vert_steps + i*mesh_size, bounds);
+
+			type = PRIMITIVE_MOTION_TRIANGLE;
+		}
+
 		if(bounds.valid()) {
 			references.push_back(BVHReference(bounds, j, i, type));
 			root.grow(bounds);
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index ccefb31..7e9b0c5 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -113,6 +113,7 @@ set(SRC_GEOM_HEADERS
 	geom/geom_bvh_subsurface.h
 	geom/geom_bvh_traversal.h
 	geom/geom_curve.h
+	geom/geom_motion_triangle.h
 	geom/geom_object.h
 	geom/geom_triangle.h
 )
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index 055b18e..20c3c7c 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -43,6 +43,7 @@
 #include "geom_object.h"
 #include "geom_curve.h"
 #include "geom_triangle.h"
+#include "geom_motion_triangle.h"
 
 CCL_NAMESPACE_BEGIN
 
diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
index d619294..994c98e 100644
--- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h
+++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
@@ -218,6 +218,10 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
 								triangle_intersect_subsurface(kg, isect_array, P, idir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
 								break;
 							}
+							case PRIMITIVE_MOTION_TRIANGLE: {
+								motion_triangle_intersect_subsurface(kg, isect_array, P, idir, ray->time, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+								break;
+							}
 							default: {
 								break;
 							}
diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h
index 1abefb5..1fd0772 100644
--- a/intern/cycles/kernel/geom/geom_bvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h
@@ -256,6 +256,10 @@ ccl_device bool BVH_FUNCTION_NAME
 								hit = triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
 								break;
 							}
+							case PRIMITIVE_MOTION_TRIANGLE: {
+								hit = motion_triangle_intersect(kg, isect, P, idir, ray->time, visibility, object, primAddr);
+								break;
+							}
 #if FEATURE(BVH_HAIR)
 							case PRIMITIVE_CURVE: {
 #if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
new file mode 100644
index 0000000..05642d8
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -0,0 +1,370 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* todo: find a better (faster) solution for this, maybe store offset per object */
+ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
+{
+	uint attr_offset = object*kernel_data.bvh.attributes_map_stride;
+	uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+	
+	while(attr_map.x != id) {
+		attr_offset += ATTR_PRIM_TYPES;
+		attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+	}
+
+	*elem = (AttributeElement)attr_map.y;
+	
+	/* return result */
+	return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+}
+
+ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3])
+{
+	if(step == numsteps) {
+		/* center step: regular vertex location */
+		verts[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
+		verts[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
+		verts[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
+	}
+	else {
+		/* center step not store in this array */
+		if(step > numsteps)
+			step--;
+
+		offset += step*numverts;
+
+		verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
+		verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
+		verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
+	}
+}
+
+ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3])
+{
+	if(step == numsteps) {
+		/* center step: regular vertex location */
+		normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x)));
+		normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y)));
+		normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)));
+	}
+	else {
+		/* center step not store in this array */
+		if(step > numsteps)
+			step--;
+
+		offset += step*numverts;
+
+		normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
+		normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
+		normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
+	}
+}
+
+/* return 3 triangle vertex locations */
+ccl_device_inline void motion_triangle_vertices(KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
+{
+	/* get motion info */
+	int numsteps, numverts;
+	object_motion_info(kg, object, &numsteps, &numverts, NULL);
+
+	/* figure out which steps we need to fetch and their interpolation factor */
+	int maxstep = numsteps*2;
+	int step = min((int)(time*maxstep), maxstep-1);
+	float t = time*maxstep - step;
+
+	/* find attribute */
+	AttributeElement elem;
+	int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+	kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+	/* fetch vertex coordinates */
+	float3 next_verts[3];
+	float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
+
+	motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
+	motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts);
+
+	/* interpolate between steps */
+	verts[0] = (1.0f - t)*verts[0] + t*next_ver

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list