diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-08-22 22:19:00 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-08-24 10:46:40 +0300 |
commit | 334208e67086530924c1172d4c993ae14508c0cf (patch) | |
tree | 43877b87e7b3bf835b9b3e70ad7971e96f5fa428 /intern | |
parent | c88c5db3601b82f347f2f54f49fae8ae173ff03b (diff) |
Cycles: Implementation of object reference nodes spatial split
This commit implements object reference node spatial split making it possible
to use spatial split for top-level BVH.
The code is not in use yet because enabling spatial split on top level BVH is
not coming for free and it needs to be investigated if it's worth in terms of
improved render times.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/bvh/bvh_build.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_split.cpp | 69 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_split.h | 18 |
3 files changed, 83 insertions, 12 deletions
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 9e93d6bccf5..13427516b01 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -234,8 +234,14 @@ BVHNode* BVHBuild::run() return NULL; /* init spatial splits */ - if(params.top_level) /* todo: get rid of this */ + if(params.top_level) { + /* NOTE: Technically it is supported by the builder but it's not really + * optimized for speed yet and not really clear yet if it has measurable + * improvement on render time. Needs some extra investigation before + * enabling spatial split for top level BVH. + */ params.use_spatial_split = false; + } spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha; spatial_right_bounds.clear(); diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 7d29f84445f..caf1b4dfc46 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -244,6 +244,7 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, } void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, int prim_index, int dim, float pos, @@ -252,25 +253,25 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, { const int *inds = mesh->triangles[prim_index].v; const float3 *verts = &mesh->verts[0]; - const float3 *v1 = &verts[inds[2]]; + float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]]; for(int i = 0; i < 3; i++) { - const float3 *v0 = v1; + float3 v0 = v1; int vindex = inds[i]; - v1 = &verts[vindex]; - float v0p = (*v0)[dim]; - float v1p = (*v1)[dim]; + v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex]; + float v0p = v0[dim]; + float v1p = v1[dim]; /* insert vertex to the boxes it belongs to. */ if(v0p <= pos) - left_bounds.grow(*v0); + left_bounds.grow(v0); if(v0p >= pos) - right_bounds.grow(*v0); + right_bounds.grow(v0); /* edge intersects the plane => insert intersection to both boxes. */ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { - float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); + float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); left_bounds.grow(t); right_bounds.grow(t); } @@ -278,6 +279,7 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, } void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, + const Transform *tfm, int prim_index, int segment_index, int dim, @@ -290,8 +292,13 @@ void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, const int k1 = k0 + 1; const float4 key0 = mesh->curve_keys[k0]; const float4 key1 = mesh->curve_keys[k1]; - const float3 v0 = float4_to_float3(key0); - const float3 v1 = float4_to_float3(key1); + float3 v0 = float4_to_float3(key0); + float3 v1 = float4_to_float3(key1); + + if(tfm != NULL) { + v0 = transform_point(tfm, v0); + v1 = transform_point(tfm, v1); + } float v0p = v0[dim]; float v1p = v1[dim]; @@ -325,6 +332,7 @@ void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref, BoundBox& right_bounds) { split_triangle_primitive(mesh, + NULL, ref.prim_index(), dim, pos, @@ -340,6 +348,7 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, BoundBox& right_bounds) { split_curve_primitive(mesh, + NULL, ref.prim_index(), PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()), dim, @@ -348,6 +357,40 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, right_bounds); } +void BVHSpatialSplit::split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + Mesh *mesh = object->mesh; + for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) { + split_triangle_primitive(mesh, + &object->tfm, + tri_idx, + dim, + pos, + left_bounds, + right_bounds); + } + for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) { + Mesh::Curve &curve = mesh->curves[curve_idx]; + for(int segment_idx = 0; + segment_idx < curve.num_keys - 1; + ++segment_idx) + { + split_curve_primitive(mesh, + &object->tfm, + curve_idx, + segment_idx, + dim, + pos, + left_bounds, + right_bounds); + } + } +} + void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, @@ -380,7 +423,11 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, right_bounds); } else { - assert(!"Unknown primitive type in BVH reference split."); + split_object_reference(ob, + dim, + pos, + left_bounds, + right_bounds); } /* intersect with original bounds. */ diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h index f9bed5f69e9..1e46bb66203 100644 --- a/intern/cycles/bvh/bvh_split.h +++ b/intern/cycles/bvh/bvh_split.h @@ -63,13 +63,21 @@ public: float pos); protected: + /* Lower-level functions which calculates boundaries of left and right nodes + * needed for spatial split. + * + * Operates directly with primitive specified by it's index, reused by higher + * level splitting functions. + */ void split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, int prim_index, int dim, float pos, BoundBox& left_bounds, BoundBox& right_bounds); void split_curve_primitive(const Mesh *mesh, + const Transform *tfm, int prim_index, int segment_index, int dim, @@ -77,6 +85,11 @@ protected: BoundBox& left_bounds, BoundBox& right_bounds); + /* Lower-level functions which calculates boundaries of left and right nodes + * needed for spatial split. + * + * Operates with BVHReference, internally uses lower level API functions. + */ void split_triangle_reference(const BVHReference& ref, const Mesh *mesh, int dim, @@ -89,6 +102,11 @@ protected: float pos, BoundBox& left_bounds, BoundBox& right_bounds); + void split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); }; /* Mixed Object-Spatial Split */ |