Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-08-22 22:19:00 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-08-24 10:46:40 +0300
commit334208e67086530924c1172d4c993ae14508c0cf (patch)
tree43877b87e7b3bf835b9b3e70ad7971e96f5fa428 /intern
parentc88c5db3601b82f347f2f54f49fae8ae173ff03b (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.cpp8
-rw-r--r--intern/cycles/bvh/bvh_split.cpp69
-rw-r--r--intern/cycles/bvh/bvh_split.h18
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 */