Update OBVHS to 0.3#8
Merged
Merged
Conversation
fe239d2 to
d2150c7
Compare
cb20d06 to
5666433
Compare
wrt non-contiguous primitive_indices (some entries are INVALID, freelist in use, etc..)
Add `PlocBuilder::full_rebuild`
83bc441 to
859514f
Compare
amirreiter
pushed a commit
to amirreiter/obvhs
that referenced
this pull request
Feb 26, 2026
Update OBVHS to 0.3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview of changes
Features for dynamically updating a
Bvh2bvh.refit_all()Refits the whole BVH from the leaf nodes up. Sizing each Aabb to exactly contain its children.bvh.remove_leaf()Removes and returns the leaf specified bynode_id.bvh.insert_leaf()Searches the tree recursively to find the best sibling for the node being inserted.bvh.remove_primitive()Removes the leaf that contains the given primitive.bvh.insert_primitive()Searches the tree recursively to find the best sibling for the primitive being inserted.bvh.primitives_to_nodesOptional mapping from primitives back to nodes. Functions that modify the BVH will keep the mapping valid. Use withbvh.init_primitives_to_nodes()&bvh.recompute_primitives_to_nodes()bvh.parentsOptional mapping from node ids to parent ids. Functions that modify the BVH will keep the mapping valid. Use withbvh.init_parents()&bvh.recompute_parents()bvh.reinsert_node()Find if there might be a better spot in the BVH for this node and move it there.PlocBuilder::partial_rebuild()The given set of leaves and the subtrees that do not include any of the given leaves will be built into a new bvh using Ploc.ReinsertionOptimizer::run_with_candidates()Restructures the BVH, optimizing given node locations.New ray traversal functions for
Bvh2&Cwbvh.These were created because
ray_traverse_dynamic()doesn't have a unified interface betweenBvh2andCwbvhanymore and is a requires a bit more boilerplate. (With the tradeoff being thatBvh2ray traversal it is now much faster)bvh.ray_traverse()Unchanged, used for closest hit.bvh.ray_traverse_miss()Helper for miss (eg. for shadow rendering)bvh.ray_traverse_anyhit()Helper for intersecting all primitives along ray (eg. for transparency)Ways to reuse allocations
PlocBuilder::build_with_bvh()Builds a new BVH using the existing allocations from an old one.ReinsertionOptimizercan now be initially created with::default()and then subsequently.run()multiple times, reusing allocations.Update to Bvh2Node
There's now two different versions of the
Bvh2Nodedepending on the newsmall_bvh2_nodefeature.small_bvh2_nodefeature is disabled, theBvh2Nodeis the same size that it was previously (48 bytes) but adds 2x32 bit user meta data fields where there was previously padding.small_bvh2_nodefeature is enabled, theBvh2Nodesize shrinks to 32 bytes, and is cast directly to an Aabb. (Taking inspiration from parry)Examples
physics.rsexample showcases how some of new features could be used for updating aBvh2that is being used in physics simulations.obj_cwbvh.rsexample shows loading and rendering an obj. This exists mostly to render a small obj scene that was added for testing.demoscene.rs,cornell_box_cwbvh.rs,obj_cwbvh.rs, andphysics.rsexamples can dynamically show render progress in a window.API changes
Bvh2::ray_traverse_dynamic()is now a bit lower level requiring theintersection_fnto test each primitive in the node and update theray.tmax, and hit info, and return whether to halt traversal or continue.ray_traverse_dynamicno longer yields on hits requiring theintersection_fnto control updates and traversal. This allows for a much faster method of traversal. ray_traverse(), ray_traverse_miss(), and ray_traverse_anyhit() have been added for convince and to regain some api overlap between cwbvh and bvh2.uses_spatial_splitsis now tracked directly on theCwBvhorBvh2so the respectivevalidate()functions no longer take this parameter.Misc
FastStacktrait that allows for creating a stack on the stack or heap depending on initialization capacity using specialization to avoid additional branching while using the stack.max_depthon the Bvh2. This is used to initialize theFastStackfor traversal allowing for deep BVHs without overrunning the stack length. Note: Generally, very deep BVHs are indicative of something pathological in the scene (like thousands of instances perfectly overlapping geometry) that will result in a BVH that is very slow to traverse. (This isn't a limitation of OBVHS, many scenes with these kinds of issues will be slow to traverse with any BVH, and would even be slow to rasterize)Bvh2::update_primitives_to_nodes()&Bvh2::init_primitives_to_nodes_if_uninit()are for computing the mapping from primitive index to node index (Ex.let node_id = primitives_to_nodes[primitive_id];). The result is stored on the Bvh2 and is used in various node insertion and removal functions. Methods that modify the Bvh2 will keep this mapping up to date if it has been initialized.Bvh2::update_parents()&Bvh2::init_parents_if_uninit()are used for computing the mapping from a given node index to that node's parent for each node in the Bvh2. They are also stored on the Bvh2, used by various other functions, and kept up-to-date by methods that modify the Bvh2 once initialized.