diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-01-17 17:13:01 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-01-26 13:14:42 +0300 |
commit | 91fe6bdcb69af4f04b083b85a46807e5f7061dde (patch) | |
tree | 69dec127a554ea21a3be65ab9bf9b93bda610659 | |
parent | 9bf3b4679e238e966a2e8fc6782c1ab97dd9c864 (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.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_build.cpp | 107 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_params.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 6 |
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); } |