diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-04-22 18:54:02 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-04-22 19:15:41 +0400 |
commit | 6974b69c61729cc80a72d78f02eb137c5097b129 (patch) | |
tree | 85642f54fffafae4f8df5129d3651292bae8a12c /intern/cycles/bvh/bvh_build.cpp | |
parent | 2108a616910dc814be13a0b640970bfe4b7eb4ce (diff) |
Cycles: optimization for hair BVH build, allow max 2 hair curves per leaf.
This gives me 14% reduction in render time for koro_final.blend.
Diffstat (limited to 'intern/cycles/bvh/bvh_build.cpp')
-rw-r--r-- | intern/cycles/bvh/bvh_build.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 9367e7b86b4..eb4cca92b6b 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -298,18 +298,41 @@ void BVHBuild::thread_build_node(InnerNode *inner, int child, BVHObjectBinning * } } +bool BVHBuild::range_within_max_leaf_size(const BVHRange& range) +{ + size_t size = range.size(); + size_t max_leaf_size = max(params.max_triangle_leaf_size, params.max_curve_leaf_size); + + if(size > max_leaf_size) + return false; + + size_t num_triangles = 0; + size_t num_curves = 0; + + for(int i = 0; i < size; i++) { + BVHReference& ref = references[range.start() + i]; + + if(ref.prim_type() & PRIMITIVE_ALL_CURVE) + num_curves++; + else if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) + num_triangles++; + } + + return (num_triangles < params.max_triangle_leaf_size) && (num_curves < params.max_curve_leaf_size); +} + /* multithreaded binning builder */ BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level) { size_t size = range.size(); - float leafSAH = params.sah_triangle_cost * range.leafSAH; - float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_triangle_cost * range.splitSAH; + float leafSAH = params.sah_primitive_cost * range.leafSAH; + float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_primitive_cost * range.splitSAH; /* have at least one inner node on top level, for performance and correct * visibility tests, since object instances do not check visibility flag */ if(!(range.size() > 0 && params.top_level && level == 0)) { /* make leaf node when threshold reached or SAH tells us */ - if(params.small_enough_for_leaf(size, level) || (size <= params.max_leaf_size && leafSAH < splitSAH)) + if(params.small_enough_for_leaf(size, level) || (range_within_max_leaf_size(range) && leafSAH < splitSAH)) return create_leaf_node(range); } |