[Bf-blender-cvs] [0e47e0c] master: Cycles: Use dedicated BVH for subsurface ray casting

Sergey Sharybin noreply at git.blender.org
Fri Mar 25 13:41:53 CET 2016


Commit: 0e47e0cc9e9b19a30717042d97cb3b8fb50132ff
Author: Sergey Sharybin
Date:   Thu Feb 25 15:12:11 2016 +0100
Branches: master
https://developer.blender.org/rB0e47e0cc9e9b19a30717042d97cb3b8fb50132ff

Cycles: Use dedicated BVH for subsurface ray casting

This commit makes it so casting subsurface rays will totally ignore all
the BVH nodes and primitives which do not belong to a current object,
making it much simpler traversal code and reduces number of intersection
tests.

Reviewers: brecht, juicyfruit, dingto, lukasstockner97

Differential Revision: https://developer.blender.org/D1823

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

M	intern/cycles/bvh/bvh.cpp
M	intern/cycles/bvh/bvh_build.cpp
M	intern/cycles/kernel/geom/geom_bvh.h
M	intern/cycles/kernel/geom/geom_bvh_subsurface.h
M	intern/cycles/kernel/geom/geom_qbvh_subsurface.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/object.cpp

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

diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 4a5f8b1..f78ad3e 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -233,7 +233,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 		Mesh *mesh = ob->mesh;
 		BVH *bvh = mesh->bvh;
 
-		if(!mesh->transform_applied) {
+		if(mesh->need_build_bvh()) {
 			if(mesh_map.find(mesh) == mesh_map.end()) {
 				prim_index_size += bvh->pack.prim_index.size();
 				tri_woop_size += bvh->pack.tri_woop.size();
@@ -268,9 +268,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 	foreach(Object *ob, objects) {
 		Mesh *mesh = ob->mesh;
 
-		/* if mesh transform is applied, that means it's already in the top
-		 * level BVH, and we don't need to merge it in */
-		if(mesh->transform_applied) {
+		/* We assume that if mesh doesn't need own BVH it was already included
+		 * into a top-level BVH and no packing here is needed.
+		 */
+		if(!mesh->need_build_bvh()) {
 			pack.object_node[object_offset++] = 0;
 			continue;
 		}
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 45b0aaa..a8b9fe0 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -180,7 +180,7 @@ void BVHBuild::add_references(BVHRange& root)
 
 	foreach(Object *ob, objects) {
 		if(params.top_level) {
-			if(ob->mesh->transform_applied) {
+			if(!ob->mesh->is_instanced()) {
 				num_alloc_references += ob->mesh->triangles.size();
 				num_alloc_references += count_curve_segments(ob->mesh);
 			}
@@ -201,7 +201,7 @@ void BVHBuild::add_references(BVHRange& root)
 
 	foreach(Object *ob, objects) {
 		if(params.top_level) {
-			if(ob->mesh->transform_applied)
+			if(!ob->mesh->is_instanced())
 				add_reference_mesh(bounds, center, ob->mesh, i);
 			else
 				add_reference_object(bounds, center, ob, i);
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index d9f4076..ad98399 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -91,27 +91,9 @@ CCL_NAMESPACE_BEGIN
 #include "geom_bvh_subsurface.h"
 #endif
 
-#if defined(__SUBSURFACE__) && defined(__INSTANCING__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_instancing
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING
-#include "geom_bvh_subsurface.h"
-#endif
-
-#if defined(__SUBSURFACE__) && defined(__HAIR__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
-#include "geom_bvh_subsurface.h"
-#endif
-
 #if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__)
 #define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
-#include "geom_bvh_subsurface.h"
-#endif
-
-#if defined(__SUBSURFACE__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair_motion
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
+#define BVH_FUNCTION_FEATURES BVH_MOTION
 #include "geom_bvh_subsurface.h"
 #endif
 
@@ -269,17 +251,6 @@ ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg,
 {
 #ifdef __OBJECT_MOTION__
 	if(kernel_data.bvh.have_motion) {
-#ifdef __HAIR__
-		if(kernel_data.bvh.have_curves) {
-			return bvh_intersect_subsurface_hair_motion(kg,
-			                                            ray,
-			                                            ss_isect,
-			                                            subsurface_object,
-			                                            lcg_state,
-			                                            max_hits);
-		}
-#endif /* __HAIR__ */
-
 		return bvh_intersect_subsurface_motion(kg,
 		                                       ray,
 		                                       ss_isect,
@@ -288,56 +259,12 @@ ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg,
 		                                       max_hits);
 	}
 #endif /* __OBJECT_MOTION__ */
-
-#ifdef __HAIR__
-	if(kernel_data.bvh.have_curves) {
-		return bvh_intersect_subsurface_hair(kg,
-		                                     ray,
-		                                     ss_isect,
-		                                     subsurface_object,
-		                                     lcg_state,
-		                                     max_hits);
-	}
-#endif /* __HAIR__ */
-
-#ifdef __KERNEL_CPU__
-
-#ifdef __INSTANCING__
-	if(kernel_data.bvh.have_instancing) {
-		return bvh_intersect_subsurface_instancing(kg,
-		                                           ray,
-		                                           ss_isect,
-		                                           subsurface_object,
-		                                           lcg_state,
-		                                           max_hits);
-	}
-#endif /* __INSTANCING__ */
-
-	return bvh_intersect_subsurface(kg,
-	                                ray,
-	                                ss_isect,
-	                                subsurface_object,
-	                                lcg_state,
-	                                max_hits);
-#else /* __KERNEL_CPU__ */
-
-#ifdef __INSTANCING__
-	return bvh_intersect_subsurface_instancing(kg,
-	                                           ray,
-	                                           ss_isect,
-	                                           subsurface_object,
-	                                           lcg_state,
-	                                           max_hits);
-#else
 	return bvh_intersect_subsurface(kg,
 	                                ray,
 	                                ss_isect,
 	                                subsurface_object,
 	                                lcg_state,
 	                                max_hits);
-#endif /* __INSTANCING__ */
-
-#endif /* __KERNEL_CPU__ */
 }
 #endif
 
diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
index b9f1a46..4380920 100644
--- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h
+++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
@@ -25,7 +25,6 @@
  * various features can be enabled/disabled. This way we can compile optimized
  * versions for each case without new features slowing things down.
  *
- * BVH_INSTANCING: object instancing
  * BVH_MOTION: motion blur rendering
  *
  */
@@ -41,17 +40,16 @@ ccl_device void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 	 * - test if pushing distance on the stack helps (for non shadow rays)
 	 * - separate version for shadow rays
 	 * - likely and unlikely for if() statements
-	 * - SSE for hair
 	 * - test restrict attribute for pointers
 	 */
-	
+
 	/* traversal stack in CUDA thread-local memory */
 	int traversalStack[BVH_STACK_SIZE];
 	traversalStack[0] = ENTRYPOINT_SENTINEL;
 
 	/* traversal variables in registers */
 	int stackPtr = 0;
-	int nodeAddr = kernel_data.bvh.root;
+	int nodeAddr = kernel_tex_fetch(__object_node, subsurface_object);
 
 	/* ray parameters in registers */
 	float3 P = ray->P;
@@ -62,14 +60,28 @@ ccl_device void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 
 	ss_isect->num_hits = 0;
 
+	const int object_flag = kernel_tex_fetch(__object_flag, subsurface_object);
+	if(!(object_flag & SD_TRANSFORM_APPLIED)) {
 #if BVH_FEATURE(BVH_MOTION)
-	Transform ob_itfm;
+		Transform ob_itfm;
+		bvh_instance_motion_push(kg,
+		                         subsurface_object,
+		                         ray,
+		                         &P,
+		                         &dir,
+		                         &idir,
+		                         &isect_t,
+		                         &ob_itfm);
+#else
+		bvh_instance_push(kg, subsurface_object, ray, &P, &dir, &idir, &isect_t);
 #endif
+		object = subsurface_object;
+	}
 
 #if defined(__KERNEL_SSE2__)
 	const shuffle_swap_t shuf_identity = shuffle_swap_identity();
 	const shuffle_swap_t shuf_swap = shuffle_swap_swap();
-	
+
 	const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
 	ssef Psplat[3], idirsplat[3];
 	shuffle_swap_t shufflexyz[3];
@@ -190,133 +202,56 @@ ccl_device void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 				float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-nodeAddr-1)*BVH_NODE_LEAF_SIZE);
 				int primAddr = __float_as_int(leaf.x);
 
-#if BVH_FEATURE(BVH_INSTANCING)
-				if(primAddr >= 0) {
-#endif
-					const int primAddr2 = __float_as_int(leaf.y);
-					const uint type = __float_as_int(leaf.w);
-
-					/* pop */
-					nodeAddr = traversalStack[stackPtr];
-					--stackPtr;
-
-					/* primitive intersection */
-					switch(type & PRIMITIVE_ALL) {
-						case PRIMITIVE_TRIANGLE: {
-							/* intersect ray against primitive */
-							for(; primAddr < primAddr2; primAddr++) {
-								kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
-								/* only primitives from the same object */
-								uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
-								if(tri_object != subsurface_object)
-									continue;
-								triangle_intersect_subsurface(kg,
-								                              &isect_precalc,
-								                              ss_isect,
-								                              P,
-								                              object,
-								                              primAddr,
-								                              isect_t,
-								                              lcg_state,
-								                              max_hits);
-							}
-							break;
+				const int primAddr2 = __float_as_int(leaf.y);
+				const uint type = __float_as_int(leaf.w);
+
+				/* pop */
+				nodeAddr = traversalStack[stackPtr];
+				--stackPtr;
+
+				/* primitive intersection */
+				switch(type & PRIMITIVE_ALL) {
+					case PRIMITIVE_TRIANGLE: {
+						/* intersect ray against primitive */
+						for(; primAddr < primAddr2; primAddr++) {
+							kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+							triangle_intersect_subsurface(kg,
+							                              &isect_precalc,
+							                              ss_isect,
+							                              P,
+							                              object,
+							                              primAddr,
+							                              isect_t,
+					

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list