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
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-01-17 17:13:01 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-01-26 13:14:42 +0300
commit91fe6bdcb69af4f04b083b85a46807e5f7061dde (patch)
tree69dec127a554ea21a3be65ab9bf9b93bda610659
parent9bf3b4679e238e966a2e8fc6782c1ab97dd9c864 (diff)
Cycles: Add option to split triangle motion primitives by time steps
Similar to the previous commit, the statistics goes as: BVH Steps Render time (sec) Memory usage (MB) 0 46 260 1 27 373 2 18 598 3 15 826 Scene used for the tests is the agent's body from one of the barber shop scenes (no textures or anything, just a diffuse material). Once again this is limited to regular (non-spatial split) BVH, Support of spatial split to this feature will come later.
-rw-r--r--intern/cycles/blender/blender_sync.cpp2
-rw-r--r--intern/cycles/bvh/bvh_build.cpp107
-rw-r--r--intern/cycles/bvh/bvh_params.h3
-rw-r--r--intern/cycles/render/mesh.cpp6
-rw-r--r--intern/cycles/render/scene.h6
5 files changed, 100 insertions, 24 deletions
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index a9b7d7d3583..f8f2303ec76 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -498,7 +498,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
- params.num_bvh_motion_curve_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
+ params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
if(background && params.shadingsystem != SHADINGSYSTEM_OSL)
params.persistent_data = r.use_persistent_data();
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 4d684e51c1b..21b8b980405 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -120,31 +120,101 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
if(mesh->has_motion_blur())
attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- size_t num_triangles = mesh->num_triangles();
+ const size_t num_triangles = mesh->num_triangles();
for(uint j = 0; j < num_triangles; j++) {
Mesh::Triangle t = mesh->get_triangle(j);
- BoundBox bounds = BoundBox::empty;
- PrimitiveType type = PRIMITIVE_TRIANGLE;
-
- t.bounds_grow(&mesh->verts[0], bounds);
-
- /* motion triangles */
- if(attr_mP) {
+ const float3 *verts = &mesh->verts[0];
+ if(attr_mP == NULL) {
+ BoundBox bounds = BoundBox::empty;
+ t.bounds_grow(verts, bounds);
+ if(bounds.valid()) {
+ references.push_back(BVHReference(bounds,
+ j,
+ i,
+ PRIMITIVE_TRIANGLE));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else if(params.num_motion_triangle_steps == 0 || params.use_spatial_split) {
+ /* Motion triangles, simple case: single node for the whole
+ * primitive. Lowest memory footprint and faster BVH build but
+ * least optimal ray-tracing.
+ */
+ /* TODO(sergey): Support motion steps for spatially split BVH. */
const size_t num_verts = mesh->verts.size();
- const size_t num_steps = mesh->motion_steps - 1;
+ const size_t num_steps = mesh->motion_steps;
const float3 *vert_steps = attr_mP->data_float3();
-
- for(size_t step = 0; step < num_steps; step++) {
+ BoundBox bounds = BoundBox::empty;
+ t.bounds_grow(verts, bounds);
+ for(size_t step = 0; step < num_steps - 1; step++) {
t.bounds_grow(vert_steps + step*num_verts, bounds);
}
-
- type = PRIMITIVE_MOTION_TRIANGLE;
+ if(bounds.valid()) {
+ references.push_back(
+ BVHReference(bounds,
+ j,
+ i,
+ PRIMITIVE_MOTION_TRIANGLE));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
}
-
- if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i, type));
- root.grow(bounds);
- center.grow(bounds.center2());
+ else {
+ /* Motion triangles, trace optimized case: we split triangle
+ * primitives into separate nodes for each of the time steps.
+ * This way we minimize overlap of neighbor curve primitives.
+ */
+ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
+ const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
+ const size_t num_verts = mesh->verts.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *vert_steps = attr_mP->data_float3();
+ /* Calculate bounding box of the previous time step.
+ * Will be reused later to avoid duplicated work on
+ * calculating BVH time step boundbox.
+ */
+ float3 prev_verts[3];
+ t.motion_verts(verts,
+ vert_steps,
+ num_verts,
+ num_steps,
+ 0.0f,
+ prev_verts);
+ BoundBox prev_bounds = BoundBox::empty;
+ prev_bounds.grow(prev_verts[0]);
+ prev_bounds.grow(prev_verts[1]);
+ prev_bounds.grow(prev_verts[2]);
+ /* Create all primitive time steps, */
+ for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
+ const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
+ float3 curr_verts[3];
+ t.motion_verts(verts,
+ vert_steps,
+ num_verts,
+ num_steps,
+ curr_time,
+ curr_verts);
+ BoundBox curr_bounds = BoundBox::empty;
+ curr_bounds.grow(curr_verts[0]);
+ curr_bounds.grow(curr_verts[1]);
+ curr_bounds.grow(curr_verts[2]);
+ BoundBox bounds = prev_bounds;
+ bounds.grow(curr_bounds);
+ if(bounds.valid()) {
+ references.push_back(
+ BVHReference(bounds,
+ j,
+ i,
+ PRIMITIVE_MOTION_TRIANGLE));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ /* Current time boundbox becomes previous one for the
+ * next time step.
+ */
+ prev_bounds = curr_bounds;
+ }
}
}
}
@@ -224,6 +294,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
prev_keys);
BoundBox prev_bounds = BoundBox::empty;
curve.bounds_grow(prev_keys, prev_bounds);
+ /* Create all primitive time steps, */
for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
float4 curr_keys[4];
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 1521fe9b5e4..233c7adacba 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -69,6 +69,9 @@ public:
*/
int num_motion_curve_steps;
+ /* Same as above, but for triangle primitives. */
+ int num_motion_triangle_steps;
+
/* fixed parameters */
enum {
MAX_DEPTH = 64,
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 1522a2dc18b..c42b32919d4 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1053,7 +1053,8 @@ void Mesh::compute_bvh(DeviceScene *dscene,
bparams.use_qbvh = params->use_qbvh;
bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
params->use_bvh_unaligned_nodes;
- bparams.num_motion_curve_steps = params->num_bvh_motion_curve_steps;
+ bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
+ bparams.num_motion_curve_steps = params->num_bvh_time_steps;
delete bvh;
bvh = BVH::create(bparams, objects);
@@ -1822,7 +1823,8 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
scene->params.use_bvh_unaligned_nodes;
- bparams.num_motion_curve_steps = scene->params.num_bvh_motion_curve_steps;
+ bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps;
+ bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps;
delete bvh;
bvh = BVH::create(bparams, scene->objects);
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 948697dd136..8768682043f 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -143,7 +143,7 @@ public:
} bvh_type;
bool use_bvh_spatial_split;
bool use_bvh_unaligned_nodes;
- int num_bvh_motion_curve_steps;
+ int num_bvh_time_steps;
bool use_qbvh;
bool persistent_data;
int texture_limit;
@@ -154,7 +154,7 @@ public:
bvh_type = BVH_DYNAMIC;
use_bvh_spatial_split = false;
use_bvh_unaligned_nodes = true;
- num_bvh_motion_curve_steps = 0;
+ num_bvh_time_steps = 0;
use_qbvh = false;
persistent_data = false;
texture_limit = 0;
@@ -165,7 +165,7 @@ public:
&& bvh_type == params.bvh_type
&& use_bvh_spatial_split == params.use_bvh_spatial_split
&& use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes
- && num_bvh_motion_curve_steps == params.num_bvh_motion_curve_steps
+ && num_bvh_time_steps == params.num_bvh_time_steps
&& use_qbvh == params.use_qbvh
&& persistent_data == params.persistent_data
&& texture_limit == params.texture_limit); }