[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