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:
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/addon/properties.py6
-rw-r--r--intern/cycles/blender/addon/ui.py4
-rw-r--r--intern/cycles/blender/blender_sync.cpp1
-rw-r--r--intern/cycles/bvh/bvh_build.cpp109
-rw-r--r--intern/cycles/bvh/bvh_params.h10
-rw-r--r--intern/cycles/render/scene.h3
6 files changed, 113 insertions, 20 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 3616b13e751..802b9b76c5d 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -528,6 +528,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Use special type BVH optimized for hair (uses more ram but renders faster)",
default=True,
)
+ cls.debug_bvh_time_steps = IntProperty(
+ name="BVH Time Steps",
+ description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
+ default=0,
+ min=0, max=16,
+ )
cls.tile_order = EnumProperty(
name="Tile Order",
description="Tile order for rendering",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 53bd208c0e7..d26ab73fac3 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -432,6 +432,10 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
col.prop(cscene, "debug_use_spatial_splits")
col.prop(cscene, "debug_use_hair_bvh")
+ row = col.row()
+ row.active = not cscene.debug_use_spatial_splits
+ row.prop(cscene, "debug_bvh_time_steps")
+
class CyclesRender_PT_layer_options(CyclesButtonsPanel, Panel):
bl_label = "Layer"
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 38b2ce19e8a..a9b7d7d3583 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -498,6 +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");
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 a045481e50f..4d684e51c1b 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -158,32 +158,101 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
size_t num_curves = mesh->num_curves();
for(uint j = 0; j < num_curves; j++) {
const Mesh::Curve curve = mesh->get_curve(j);
- PrimitiveType type = PRIMITIVE_CURVE;
const float *curve_radius = &mesh->curve_radius[0];
-
for(int k = 0; k < curve.num_keys - 1; k++) {
- BoundBox bounds = BoundBox::empty;
- curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
-
- /* motion curve */
- if(curve_attr_mP) {
+ if(curve_attr_mP == NULL) {
+ /* Really simple logic for static hair. */
+ BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
+ if(bounds.valid()) {
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
+ references.push_back(BVHReference(bounds, j, i, packed_type));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else if(params.num_motion_curve_steps == 0 || params.use_spatial_split) {
+ /* Simple case of motion curves: single node for the while
+ * shutter time. Lowest memory usage but less optimal
+ * rendering.
+ */
+ /* TODO(sergey): Support motion steps for spatially split BVH. */
+ BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
const size_t num_keys = mesh->curve_keys.size();
- const size_t num_steps = mesh->motion_steps - 1;
+ const size_t num_steps = mesh->motion_steps;
const float3 *key_steps = curve_attr_mP->data_float3();
-
- for(size_t step = 0; step < num_steps; step++) {
- curve.bounds_grow(k, key_steps + step*num_keys, curve_radius, bounds);
+ for(size_t step = 0; step < num_steps - 1; step++) {
+ curve.bounds_grow(k,
+ key_steps + step*num_keys,
+ curve_radius,
+ bounds);
+ }
+ if(bounds.valid()) {
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+ references.push_back(BVHReference(bounds,
+ j,
+ i,
+ packed_type));
+ root.grow(bounds);
+ center.grow(bounds.center2());
}
-
- type = PRIMITIVE_MOTION_CURVE;
}
-
- if(bounds.valid()) {
- int packed_type = PRIMITIVE_PACK_SEGMENT(type, k);
-
- references.push_back(BVHReference(bounds, j, i, packed_type));
- root.grow(bounds);
- center.grow(bounds.center2());
+ else {
+ /* Motion curves, trace optimized case: we split curve keys
+ * 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_steps = mesh->motion_steps;
+ const float3 *curve_keys = &mesh->curve_keys[0];
+ const float3 *key_steps = curve_attr_mP->data_float3();
+ const size_t num_keys = mesh->curve_keys.size();
+ /* Calculate bounding box of the previous time step.
+ * Will be reused later to avoid duplicated work on
+ * calculating BVH time step boundbox.
+ */
+ float4 prev_keys[4];
+ curve.cardinal_motion_keys(curve_keys,
+ curve_radius,
+ key_steps,
+ num_keys,
+ num_steps,
+ 0.0f,
+ k - 1, k, k + 1, k + 2,
+ prev_keys);
+ BoundBox prev_bounds = BoundBox::empty;
+ curve.bounds_grow(prev_keys, prev_bounds);
+ 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];
+ curve.cardinal_motion_keys(curve_keys,
+ curve_radius,
+ key_steps,
+ num_keys,
+ num_steps,
+ curr_time,
+ k - 1, k, k + 1, k + 2,
+ curr_keys);
+ BoundBox curr_bounds = BoundBox::empty;
+ curve.bounds_grow(curr_keys, curr_bounds);
+ BoundBox bounds = prev_bounds;
+ bounds.grow(curr_bounds);
+ if(bounds.valid()) {
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+ references.push_back(BVHReference(bounds,
+ j,
+ i,
+ packed_type));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ /* Current time boundbox becomes previous one for the
+ * next time step.
+ */
+ prev_bounds = curr_bounds;
+ }
}
}
}
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 6d426475737..1521fe9b5e4 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -61,6 +61,14 @@ public:
*/
bool use_unaligned_nodes;
+ /* Split time range to this number of steps and create leaf node for each
+ * of this time steps.
+ *
+ * Speeds up rendering of motion curve primitives in the cost of higher
+ * memory usage.
+ */
+ int num_motion_curve_steps;
+
/* fixed parameters */
enum {
MAX_DEPTH = 64,
@@ -91,6 +99,8 @@ public:
use_unaligned_nodes = false;
primitive_mask = PRIMITIVE_ALL;
+
+ num_motion_curve_steps = 0;
}
/* SAH costs */
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index df9363cc768..948697dd136 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -143,6 +143,7 @@ public:
} bvh_type;
bool use_bvh_spatial_split;
bool use_bvh_unaligned_nodes;
+ int num_bvh_motion_curve_steps;
bool use_qbvh;
bool persistent_data;
int texture_limit;
@@ -153,6 +154,7 @@ public:
bvh_type = BVH_DYNAMIC;
use_bvh_spatial_split = false;
use_bvh_unaligned_nodes = true;
+ num_bvh_motion_curve_steps = 0;
use_qbvh = false;
persistent_data = false;
texture_limit = 0;
@@ -163,6 +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
&& use_qbvh == params.use_qbvh
&& persistent_data == params.persistent_data
&& texture_limit == params.texture_limit); }