three-mesh-bvh
June 29, 2026 ยท View on GitHub
Constants
CENTER
CENTER: number
Option for splitting each BVH node down the center of the longest axis of the bounds.
This is the fastest construction option and will yield a good, performant bounds.
AVERAGE
AVERAGE: number
Option for splitting each BVH node at the average point along the longest axis for all triangle centroids in the bounds.
This strategy may be better than CENTER with some geometry.
SAH
SAH: number
Option to use a Surface Area Heuristic to split the bounds more optimally. This SAH implementation tests 32 discrete splits in each node along each axis to determine which split is the lowest cost.
This is the slowest construction option but will yield the best bounds of the three options and use the least memory.
NOT_INTERSECTED
NOT_INTERSECTED: number
Indicates the shape did not intersect the given bounding box.
INTERSECTED
INTERSECTED: number
Indicates the shape did intersect the given bounding box.
CONTAINED
CONTAINED: number
Indicate the shape entirely contains the given bounding box.
Shader and Texture Packing API
bvh_ray_functions
bvh_ray_functions: string
Set of shader functions used for interacting with the packed BVH in a shader and sampling VertexAttributeTextures. Provides ray intersection functions. See src/webgl/glsl for full implementations and declarations.
Accessed as BVHShaderGLSL.bvh_ray_functions.
common_functions
common_functions: string
Set of shader functions used for interacting with the packed BVH in a shader and sampling
VertexAttributeTextures. Provides common utility functions including texelFetch1D. See
src/webgl/glsl
for full implementations and declarations.
Accessed as BVHShaderGLSL.common_functions.
bvh_distance_functions
bvh_distance_functions: string
Set of shader functions used for interacting with the packed BVH in a shader and sampling VertexAttributeTextures. Provides distance query functions. See src/webgl/glsl for full implementations and declarations.
Accessed as BVHShaderGLSL.bvh_distance_functions.
bvh_struct_definitions
bvh_struct_definitions: string
Set of shader structs and defined constants used for interacting with the packed BVH in a shader. See src/webgl/glsl/bvh_struct_definitions.glsl.js for full implementations and declarations.
Accessed as BVHShaderGLSL.bvh_struct_definitions.
BVH
Abstract base class for BVH implementations. Provides core tree traversal and spatial query
methods. Subclasses implement primitive-specific logic by overriding writePrimitiveBounds
and related internal methods.
.shiftPrimitiveOffsets
shiftPrimitiveOffsets( offset: number ): void
Adjusts all primitive offsets stored in the BVH leaf nodes by the given value. Useful when geometry buffers have been shifted or compacted (e.g. when merging geometries).
.traverse
traverse( callback: function, rootIndex = 0: number ): void
Traverses all nodes of the BVH, invoking a callback for each node.
For leaf nodes the callback receives ( depth, isLeaf, boundingData, offset, count ).
For internal nodes it receives ( depth, isLeaf, boundingData, splitAxis ) and may
return true to stop descending into that node's children.
.refit
refit(): void
Refits all BVH node bounds to reflect the current primitive positions. Faster than rebuilding the BVH but produces a less optimal tree after large vertex deformations.
.getBoundingBox
getBoundingBox( target: Box3 ): Box3
Computes the axis-aligned bounding box of all primitives in the BVH.
.shapecast
shapecast(
{
intersectsBounds: (
box: Box3,
isLeaf: boolean,
score: number | undefined,
depth: number,
nodeIndex: number
) => number,
intersectsRange?: (
offset: number,
count: number,
contained: boolean,
depth: number,
nodeIndex: number,
box: Box3
) => boolean,
boundsTraverseOrder?: (
box: Box3
) => number,
}
): boolean
A generalized traversal function for performing spatial queries against the BVH. Returns
true as soon as a primitive has been reported as intersected. The tree is traversed
depth-first; boundsTraverseOrder controls which child is visited first. Returning
CONTAINED from intersectsBounds skips further child traversal and intersects all
primitives in that subtree immediately.
.bvhcast
bvhcast(
otherBvh: BVH,
matrixToLocal: Matrix4,
{
intersectsRanges: (
offset1: number,
count1: number,
offset2: number,
count2: number,
depth1: number,
nodeIndex1: number,
depth2: number,
nodeIndex2: number
) => boolean,
}
): boolean
Simultaneously traverses two BVH structures to find intersecting primitive pairs. Returns
true as soon as any intersection is reported. Both trees are traversed depth-first with
alternating descent. matrixToLocal transforms otherBvh into the local space of this BVH.
GeometryBVH
extends BVH
Abstract base class for geometry-backed BVH implementations. Handles geometry
indexing, indirect mode, and bounding box initialization. Subclasses implement
primitive-specific bounds computation and raycasting via writePrimitiveBounds
and raycastObject3D.
.indirect
readonly indirect: boolean
Whether the BVH was built in indirect mode.
.geometry
readonly geometry: BufferGeometry
The geometry this BVH was built from.
.constructor
constructor(
geometry: BufferGeometry,
{
// Split strategy: `CENTER`, `AVERAGE`, or `SAH`.
strategy = CENTER: number,
// Maximum tree depth. Note that this can cause the target leaf
// size to not be met if the tree is truncated.
maxDepth = 40: number,
// The target number of primitives per leaf node. Note that
// this is a soft limit and generation strategies like SAH will
// terminate early if the heuristic determines.
targetLeafSize = 10: number,
// Set `geometry.boundingBox` if not already present.
setBoundingBox = true: boolean,
// Use `SharedArrayBuffer` for BVH root buffers.
useSharedArrayBuffer = false: boolean,
// Build using an indirect buffer, leaving the original index
// unmodified.
indirect = false: boolean,
// Log build progress to the console.
verbose = true: boolean,
// Called with a progress value in [0, 1] during build.
onProgress = null: function | null,
// Restrict the BVH to a specific geometry group range.
range = null: Object | null,
}
)
LineSegmentsBVH
extends GeometryBVH
BVH for THREE.LineSegments geometries. Each BVH primitive represents one line segment
(two consecutive vertices).
.shapecast
shapecast(
{
intersectsBounds: (
box: Box3,
isLeaf: boolean,
score: number | undefined,
depth: number,
nodeIndex: number
) => number,
intersectsLine?: (
line: Line3,
index: number,
contained: boolean,
depth: number
) => boolean,
intersectsRange?: (
offset: number,
count: number,
contained: boolean,
depth: number,
nodeIndex: number,
box: Box3
) => boolean,
boundsTraverseOrder?: (
box: Box3
) => number,
}
): boolean
Performs a spatial query against the BVH. Extends the base shapecast with an
intersectsLine callback that is called once per line segment primitive in leaf nodes.
LineLoopBVH
extends LineSegmentsBVH
BVH for THREE.LineLoop geometries. Forces indirect mode since the loop structure
requires that the index buffer remain unmodified.
.constructor
constructor( geometry: BufferGeometry, options: Object )
LineBVH
extends LineLoopBVH
BVH for THREE.Line geometries. Like LineLoopBVH but excludes the final closing
segment so the open line is accurately represented.
.constructor
constructor( geometry: BufferGeometry, options: Object )
MeshBVH
extends GeometryBVH
The MeshBVH generation process modifies the geometry's index bufferAttribute in place to save memory. The BVH construction will use the geometry's boundingBox if it exists or set it if it does not. The BVH will no longer work correctly if the index buffer is modified.
Only triangles within the geometry's draw range (or provided range option) are included in the
BVH. When a geometry has multiple groups, only triangles within the defined group ranges are
included. Triangles in gaps between groups are excluded.
Note that all query functions expect arguments in local space of the BVH and return results in
local space, as well. If world space results are needed they must be transformed into world space
using object.matrixWorld.
static .serialize
static serialize(
bvh: MeshBVH,
{
// If `true`, the index and BVH root buffers are cloned so
// the serialized data is independent of the live BVH.
cloneBuffers = true: boolean,
}
): SerializedBVH
Generates a representation of the complete bounds tree and the geometry index buffer which
can be used to recreate a bounds tree using the deserialize function. The serialize and
deserialize functions can be used to generate a MeshBVH asynchronously in a background web
worker to prevent the main thread from stuttering. The BVH roots buffer stored in the
serialized representation are the same as the ones used by the original BVH so they should
not be modified. If SharedArrayBuffers are used then the same BVH memory can be used for
multiple BVH in multiple WebWorkers.
static .deserialize
static deserialize(
data: SerializedBVH,
geometry: BufferGeometry,
{
// If `true`, sets `geometry.index` from the serialized index
// buffer (creating one if none exists).
setIndex = true: boolean,
}
): MeshBVH
Returns a new MeshBVH instance from the serialized data. geometry is the geometry used
to generate the original BVH data was derived from. The root buffers stored in data
are set directly on the new BVH so the memory is shared.
.resolveTriangleIndex
readonly resolveTriangleIndex: function
Helper function for use when indirect is set to true. This function takes a triangle
index in the BVH layout and returns the associated triangle index in the geometry index
buffer or position attribute.
.constructor
constructor( geometry: BufferGeometry, options: Object )
.shiftTriangleOffsets
shiftTriangleOffsets( offset: number ): void
Adjusts all triangle offsets stored in the BVH by the given offset. This is useful when the
triangle data has been compacted or shifted in the geometry buffers (e.g. in BatchedMesh
when geometries are compacted using the 'optimize' function or constructing a 'merged' BVH).
This function only adjusts the BVH to point to different triangles in the geometry. The
geometry's index buffer and/or position attributes must be updated separately to match.
.raycastObject3D
raycastObject3D(
object: Object3D,
raycaster: Raycaster,
intersects = []: Array<Intersection>
): Array<Intersection>
A convenience function for performing a raycast based on a mesh. Results are formed like three.js raycast results in world frame.
.refit
refit( nodeIndices = null: Set<number> | Array<number> | null ): void
Refit the node bounds to the current triangle positions. This is quicker than regenerating
a new BVH but will not be optimal after significant changes to the vertices. nodeIndices
is a set of node indices (provided by the shapecast function) that need to be refit
including all internal nodes.
.raycast
raycast(
ray: Ray,
materialOrSide = FrontSide: number | Material | Array<Material>,
near = 0: number,
far = Infinity: number
): Array<Intersection>
Returns all raycast triangle hits in unsorted order. It is expected that ray is in the
frame of the BVH already. Likewise the returned results are also provided in the local
frame of the BVH. The side identifier is used to determine the side to check when
raycasting or a material with the given side field can be passed. If an array of materials
is provided then it is expected that the geometry has groups and the appropriate material
side is used per group.
Note that unlike three.js' Raycaster results the points and distances in the intersections
returned from this function are relative to the local frame of the MeshBVH. When using the
acceleratedRaycast function as an override for Mesh.raycast they are transformed into
world space to be consistent with three's results.
.raycastFirst
raycastFirst(
ray: Ray,
materialOrSide = FrontSide: number | Material | Array<Material>,
near = 0: number,
far = Infinity: number
): Intersection | null
Returns the first raycast hit in the model. This is typically much faster than returning
all hits. See raycast for information on the side and material options as well as the
frame of the returned intersections.
.intersectsGeometry
intersectsGeometry(
otherGeometry: BufferGeometry,
geometryToBvh: Matrix4
): boolean
Returns whether or not the mesh intersects the given geometry.
The geometryToBvh parameter is the transform of the geometry in the BVH's local frame.
Performance improves considerably if the provided geometry also has a boundsTree.
.shapecast
shapecast(
{
intersectsBounds: (
box: Box3,
isLeaf: boolean,
score: number | undefined,
depth: number,
nodeIndex: number
) => number,
intersectsTriangle?: (
triangle: ExtendedTriangle,
index: number,
contained: boolean,
depth: number
) => boolean,
intersectsRange?: (
offset: number,
count: number,
contained: boolean,
depth: number,
nodeIndex: number,
box: Box3
) => boolean,
boundsTraverseOrder?: (
box: Box3
) => number,
}
): boolean
A generalized cast function that can be used to implement intersection logic for custom
shapes. This is used internally for intersectsBox, intersectsSphere, and more. The
function returns as soon as a triangle has been reported as intersected and returns true
if a triangle has been intersected.
.bvhcast
bvhcast(
otherBvh: MeshBVH,
matrixToLocal: Matrix4,
{
intersectsRanges?: (
offset1: number,
count1: number,
offset2: number,
count2: number,
depth1: number,
nodeIndex1: number,
depth2: number,
nodeIndex2: number
) => boolean,
intersectsTriangles?: (
triangle1: ExtendedTriangle,
triangle2: ExtendedTriangle,
triangleIndex1: number,
triangleIndex2: number,
depth1: number,
nodeIndex1: number,
depth2: number,
nodeIndex2: number
) => boolean,
}
): boolean
A generalized cast function that traverses two BVH structures simultaneously to perform
intersection tests between them. This is used internally by intersectsGeometry. The
function returns true as soon as a triangle pair has been reported as intersected by
the callbacks.
matrixToLocal is a Matrix4 that transforms otherBvh into the local space of this BVH.
The other BVH's triangles are transformed by this matrix before intersection tests.
.intersectsBox
intersectsBox( box: Box3, boxToBvh: Matrix4 ): boolean
Returns whether or not the mesh intersects the given box.
The boxToBvh parameter is the transform of the box in the meshes frame.
.intersectsSphere
intersectsSphere( sphere: Sphere ): boolean
Returns whether or not the mesh intersects the given sphere.
.closestPointToGeometry
closestPointToGeometry(
otherGeometry: BufferGeometry,
geometryToBvh: Matrix4,
target1 = {}: HitPointInfo,
target2 = {}: HitPointInfo,
minThreshold = 0: number,
maxThreshold = Infinity: number
): HitPointInfo | null
Computes the closest distance from the geometry to the mesh and puts the closest point on
the mesh in target1 (in the frame of the BVH) and the closest point on the other
geometry in target2 (in the geometry frame). If target1 is not provided a new Object
is created and returned from the function.
The geometryToBvh parameter is the transform of the geometry in the BVH's local frame.
If a point is found that is closer than minThreshold then the function will return that
result early. Any triangles or points outside of maxThreshold are ignored. If no point
is found within the min / max thresholds then null is returned and the target objects
are not modified.
The returned faceIndex in target1 and target2 can be used with the standalone function
getTriangleHitPointInfo to obtain more information like UV coordinates, triangle normal
and materialIndex.
Note that this function can be very slow if geometry does not have a
geometry.boundsTree computed.
.closestPointToPoint
closestPointToPoint(
point: Vector3,
target = {}: HitPointInfo,
minThreshold = 0: number,
maxThreshold = Infinity: number
): HitPointInfo | null
Computes the closest distance from the point to the mesh and gives additional information
in target. The target can be left undefined to default to a new object which is
ultimately returned by the function.
If a point is found that is closer than minThreshold then the function will return that
result early. Any triangles or points outside of maxThreshold are ignored. If no point
is found within the min / max thresholds then null is returned and the target object
is not modified.
The returned faceIndex can be used with the standalone function getTriangleHitPointInfo
to obtain more information like UV coordinates, triangle normal and materialIndex.
PointsBVH
extends GeometryBVH
BVH for THREE.Points geometries. Each BVH primitive represents a single point.
.shapecast
shapecast(
{
intersectsBounds: (
box: Box3,
isLeaf: boolean,
score: number | undefined,
depth: number,
nodeIndex: number
) => number,
intersectsPoint?: (
point: Vector3,
index: number,
contained: boolean,
depth: number
) => boolean,
intersectsRange?: (
offset: number,
count: number,
contained: boolean,
depth: number,
nodeIndex: number,
box: Box3
) => boolean,
boundsTraverseOrder?: (
box: Box3
) => number,
}
): boolean
Performs a spatial query against the BVH. Extends the base shapecast with an
intersectsPoint callback that is called once per point primitive in leaf nodes.
SkinnedMeshBVH
extends GeometryBVH
BVH for SkinnedMesh objects. Computes primitive bounds using
SkinnedMesh.getVertexPosition so the tree reflects the current posed state
of the mesh. Call refit() after updating the skeleton to keep bounds accurate.
.constructor
constructor( mesh: SkinnedMesh, options: Object )
.shapecast
shapecast(
{
intersectsBounds: (
box: Box3,
isLeaf: boolean,
score: number | undefined,
depth: number,
nodeIndex: number
) => number,
intersectsTriangle?: (
triangle: ExtendedTriangle,
index: number,
contained: boolean,
depth: number
) => boolean,
intersectsRange?: (
offset: number,
count: number,
contained: boolean,
depth: number,
nodeIndex: number,
box: Box3
) => boolean,
boundsTraverseOrder?: (
box: Box3
) => number,
}
): boolean
Performs a spatial query against the BVH. Extends the base shapecast with an
intersectsTriangle callback that is called once per triangle primitive in leaf nodes.
ObjectBVH
extends BVH
BVH built from a scene hierarchy rather than a single geometry. Each leaf holds one Object3D (or one instance of an InstancedMesh/BatchedMesh), enabling accelerated raycasting and spatial queries across many objects at once.
.constructor
constructor(
root: Object3D | Array<Object3D>,
{
// Use vertex-level bounds instead of cached bounding boxes.
precise = false: boolean,
// Treat each instance of InstancedMesh/BatchedMesh as a
// separate primitive.
includeInstances = true: boolean,
}
)
.getObjectFromId
getObjectFromId( compositeId: number ): Object3D
Returns the Object3D associated with a composite id as provided to intersectsObject.
.getInstanceFromId
getInstanceFromId( compositeId: number ): number
Returns the instance index associated with a composite id as provided to intersectsObject.
.shapecast
shapecast(
{
intersectsBounds: (
box: Box3,
isLeaf: boolean,
score: number | undefined,
depth: number,
nodeIndex: number
) => number,
intersectsObject?: (
object: Object3D,
instanceId: number,
contained: boolean,
depth: number
) => boolean,
intersectsRange?: (
offset: number,
count: number,
contained: boolean,
depth: number,
nodeIndex: number,
box: Box3
) => boolean,
boundsTraverseOrder?: (
box: Box3
) => number,
}
): boolean
Performs a spatial query against the BVH. Extends the base shapecast with an
intersectsObject callback that is called once per object primitive in leaf nodes.
BVHHelper
extends Group
A THREE.Group that visualizes a BVH as wireframe bounding boxes or solid
face overlays. Attach it as a sibling of the mesh in the scene graph and
call update() whenever the mesh's BVH or world transform changes.
.color
readonly color: Color
Shortcut to edgeMaterial.color.
.opacity
opacity: number
Opacity applied to both edge and mesh materials.
.depth
depth: number
.mesh
mesh: Object3D | null
.bvh
bvh: GeometryBVH | null
.displayParents
displayParents: boolean
.displayEdges
displayEdges: boolean
.instanceId
instanceId: number
.edgeMaterial
edgeMaterial: LineBasicMaterial
Material used when rendering in wireframe edge mode.
.meshMaterial
meshMaterial: MeshBasicMaterial
Material used when rendering in solid face mode.
.constructor
constructor( mesh = null: Object3D | GeometryBVH | null, bvh = null: GeometryBVH | number | null, depth = 10: number )
.update
update(): void
Rebuilds the helper's display geometry from the current BVH state. Must
be called after changes to the BVH, depth, displayParents, or
displayEdges.
.dispose
dispose(): void
Disposes of the materials and geometries used by the helper.
ExtendedTriangle
extends Triangle
An extended version of three.js' Triangle class. A variety of derivative values are cached on
the object to accelerate the intersection functions. .needsUpdate must be set to true when
modifying the triangle parameters.
.needsUpdate
needsUpdate: boolean
Indicates that the triangle fields have changed so cached variables to accelerate other
function execution can be updated. Must be set to true after modifying the triangle
a, b, c fields.
.intersectsSphere
intersectsSphere( sphere: Sphere ): boolean
Returns whether the triangle intersects the given sphere.
.closestPointToSegment
closestPointToSegment(
segment: Line3,
target1: Vector3,
target2: Vector3
): number
Returns the distance to the provided line segment. target1 and target2 are set to the
closest points on the triangle and segment respectively.
.intersectsTriangle
intersectsTriangle(
other: Triangle,
target: Line3,
suppressLog = false: boolean
): boolean
Returns whether the triangles intersect. target is set to the line segment representing
the intersection.
.distanceToPoint
distanceToPoint( point: Vector3 ): number
Returns the distance to the provided point.
.distanceToTriangle
distanceToTriangle(
other: Triangle,
target1: Vector3,
target2: Vector3
): number
Returns the distance to the provided triangle.
VertexAttributeTexture
Float, Uint, and Int VertexAttributeTexture implementations are designed to simplify the
efficient packing of a three.js BufferAttribute into a texture. An instance can be treated as a
texture and when passing as a uniform to a shader they should be used as a sampler2d,
usampler2d, and isampler2d when using the Float, Uint, and Int texture types respectively.
extends THREE.DataTexture
.overrideItemSize
overrideItemSize: number
Treats BufferAttribute.itemSize as though it were set to this value when packing the
buffer attribute texture. Throws an error if the value does not divide evenly into the
length of the BufferAttribute buffer (count * itemSize % overrideItemSize).
Specifically used to pack geometry indices into an RGB texture rather than an Red texture.
.updateFrom
updateFrom( attribute: BufferAttribute ): void
Updates the texture to have the data contained in the passed BufferAttribute using the
BufferAttribute itemSize field, normalized field, and TypedArray layout to determine
the appropriate texture layout, format, and type. The texture dimensions will always be
square. Because these are intended to be sampled as 1D arrays the width of the texture must
be taken into account to derive a sampling uv. See texelFetch1D in shaderFunctions.
IntVertexAttributeTexture
extends VertexAttributeTexture
A VertexAttributeTexture that forces the signed integer texture type.
UIntVertexAttributeTexture
extends VertexAttributeTexture
A VertexAttributeTexture that forces the unsigned integer texture type.
FloatVertexAttributeTexture
extends VertexAttributeTexture
A VertexAttributeTexture that forces the float texture type.
GenerateMeshBVHWorker
extends WorkerBase
Helper class for generating a MeshBVH for a given geometry in asynchronously in a worker. The
geometry position and index buffer attribute ArrayBuffers are transferred to the Worker while
the BVH is being generated meaning the geometry will be unavailable to use while the BVH is
being processed unless SharedArrayBuffers are used. They will be automatically replaced when
the MeshBVH is finished generating.
NOTE It's best to reuse a single instance of this class to avoid the overhead of instantiating a new Worker.
.running
running: boolean
Flag indicating whether or not a BVH is already being generated in the worker.
.generate
generate(
geometry: BufferGeometry,
{
// Callback invoked with a `[0, 1]` progress value as the BVH
// is built.
onProgress?: function,
}
): Promise<MeshBVH>
Generates a MeshBVH instance for the given geometry with the given options in a WebWorker.
Returns a Promise that resolves with the generated MeshBVH. Throws if already running.
.dispose
dispose(): void
Terminates the worker.
MeshBVHUniformStruct
A shader uniform object corresponding to the BVH shader struct defined in shaderStructs. The
object contains four textures containing information about the BVH and geometry so it can be
queried in a shader using the bvh intersection functions defined in shaderFunctions. This object
is intended to be used as a shader uniform and read in the shader as a BVH struct.
.updateFrom
updateFrom( bvh: MeshBVH ): void
Updates the object and associated textures with data from the provided BVH.
.dispose
dispose(): void
Dispose of the associated textures.
OrientedBox
An oriented version of three.js' Box3 class. A variety of derivative values are cached on the
object to accelerate the intersection functions. .needsUpdate must be set to true when
modifying the box parameters.
.min
min: Vector3
.max
max: Vector3
.matrix
matrix: Matrix4
Matrix transformation applied to the box.
.needsUpdate
needsUpdate: boolean
Indicates that the bounding box fields have changed so cached variables to accelerate
other function execution can be updated. Must be set to true after modifying the
oriented box min, max, matrix fields.
.constructor
constructor( min: Vector3, max: Vector3, matrix: Matrix4 )
.set
set( min: Vector3, max: Vector3, matrix: Matrix4 ): void
Sets the oriented box parameters.
.intersectsBox
intersectsBox( box: Box3 ): boolean
Returns true if intersecting with the provided box.
.intersectsTriangle
intersectsTriangle( triangle: Triangle ): boolean
Returns true if intersecting with the provided triangle.
.closestPointToPoint
closestPointToPoint( point: Vector3, target: Vector3 ): number
Returns the distance to the provided point. Sets target to the closest point on the surface
of the box if provided.
.distanceToPoint
distanceToPoint( point: Vector3 ): number
Returns the distance to the provided point.
.distanceToBox
distanceToBox(
box: Box3,
threshold = 0: number,
target1: Vector3,
target2: Vector3
): number
Returns the distance to the provided box. threshold is an optional distance to return early
if the distance is found to be within it. target1 and target2 are set to the points on the
surface of this box and the box argument respectively.
ParallelMeshBVHWorker
A drop-in replacement for GenerateMeshBVHWorker that distributes BVH construction across
multiple Web Workers in parallel for faster builds on large geometry. Requires
SharedArrayBuffer support (cross-origin isolated context). Falls back to a single-threaded
GenerateMeshBVHWorker automatically if SharedArrayBuffer is unavailable.
Exposes the same API as GenerateMeshBVHWorker: generate, dispose, running, and
maxWorkerCount.
StaticGeometryGenerator
A utility class for taking a set of SkinnedMeshes or morph target geometry and baking it into a single, static geometry that a BVH can be generated for.
.meshes
meshes: Array<Mesh>
.useGroups
useGroups: boolean
If true then groups are used to support an array of materials on the mesh.
.applyWorldTransforms
applyWorldTransforms: boolean
Whether to transform the vertices of the geometry by the world transforms of each mesh when generating.
.attributes
attributes: Array<string>
The set of attributes to copy onto the static geometry.
.constructor
constructor( meshes: Object3D | Array<Object3D> )
Takes an array of object hierarchies to bake into a single static geometry.
.getMaterials
getMaterials(): Array<Material>
Returns an array of materials for the meshes to be merged. These can be used alongside the
generated geometry when creating a mesh: new Mesh( geometry, generator.getMaterials() ).
.generate
generate( targetGeometry: BufferGeometry ): BufferGeometry
Generates a single, static geometry for the passed meshes. When generating for the first time an empty target geometry is expected. The same generated geometry can be passed into the function on subsequent calls to update the geometry in place to save memory. An error will be thrown if the attributes or geometry on the meshes to bake has been changed and are incompatible lengths, types, etc.
On subsequent calls the "index" buffer will not be modified so any BVH generated for the
geometry is unaffected. Once the geometry is updated the MeshBVH.refit function can be
called to update the BVH.
HitPointInfo
.point
point: Vector3
The closest point on the mesh surface.
.distance
distance: number
Distance from the query point to the closest point.
.faceIndex
faceIndex: number
Index of the triangle containing the closest point. Can be
passed to getTriangleHitPointInfo to retrieve UV, normal, and material index.
HitTriangleInfo
.face
face: Object
Triangle vertex indices, material index, and face normal.
.uv
uv: Vector2 | null
UV coordinates at the hit point, or null if no UV attribute is present.
.barycoord
barycoord: Vector3
Barycentric coordinates of the hit point within the triangle.
SerializedBVH
Plain-object representation of a MeshBVH produced by MeshBVH.serialize and
consumed by MeshBVH.deserialize. Suitable for transfer across WebWorker boundaries
or storage, with optional buffer sharing via SharedArrayBuffer.
.roots
roots: Array<ArrayBuffer>
BVH root node buffers.
.index
index: Int32Array | Uint32Array | Uint16Array | null
Serialized geometry index buffer.
.indirectBuffer
indirectBuffer: Uint32Array | Uint16Array | null
Indirect primitive index buffer, or null
if the BVH was not built in indirect mode.
Extension Utilities
acceleratedRaycast
acceleratedRaycast(
raycaster: Raycaster,
intersects: Array<Intersection>
): void
An accelerated raycast function with the same signature as THREE.Mesh.raycast. Uses the BVH
for raycasting if it's available otherwise it falls back to the built-in approach. The results
of the function are designed to be identical to the results of the conventional
THREE.Mesh.raycast results.
If the raycaster object being used has a property firstHitOnly set to true, then the
raycasting will terminate as soon as it finds the closest intersection to the ray's origin and
return only that intersection. This is typically several times faster than searching for all
intersections.
computeBoundsTree
computeBoundsTree( options: Object ): GeometryBVH
A pre-made BufferGeometry extension function that builds a new BVH, assigns it to boundsTree
for BufferGeometry, and applies the new index buffer to the geometry. Comparable to
computeBoundingBox and computeBoundingSphere.
THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
disposeBoundsTree
disposeBoundsTree(): void
A BufferGeometry extension function that disposes of the BVH.
THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;
computeBatchedBoundsTree
computeBatchedBoundsTree(
index = -1: number,
options: Object
): GeometryBVH | Array<GeometryBVH> | null
Equivalent of computeBoundsTree for BatchedMesh. Creates the
BatchedMesh.boundsTrees array if it does not exist. If index is -1
BVHs for all available geometries are generated and the full array is
returned; otherwise only the BVH at that geometry index is generated and
returned.
THREE.BatchedMesh.prototype.computeBoundsTree = computeBatchedBoundsTree;
disposeBatchedBoundsTree
disposeBatchedBoundsTree( index = -1: number ): void
Equivalent of disposeBoundsTree for BatchedMesh. Sets entries in
BatchedMesh.boundsTrees to null. If index is -1 all BVHs are
disposed; otherwise only the BVH at that geometry index is disposed.
THREE.BatchedMesh.prototype.disposeBoundsTree = disposeBatchedBoundsTree;
Functions
getTriangleHitPointInfo
getTriangleHitPointInfo(
point: Vector3,
geometry: BufferGeometry,
triangleIndex: number,
target: HitTriangleInfo
): HitTriangleInfo
Computes hit-point information for a point on a triangle within a BufferGeometry. Returns
the face vertex indices, face normal, material index, UV coordinates, and barycentric coordinates.
Useful for retrieving detailed hit data after a call to MeshBVH.closestPointToPoint or
MeshBVH.closestPointToGeometry.
Debug Functions
BVHExtremes
.nodeCount
nodeCount: number
Total number of nodes in the tree including leaf nodes.
.leafNodeCount
leafNodeCount: number
Total number of leaf nodes in the tree.
.surfaceAreaScore
surfaceAreaScore: number
Total tree score based on the surface area heuristic.
Lower is better. Useful for comparing tree quality and performance, and for detecting
degradation after MeshBVH.refit calls.
.depth
depth: Object
Min and max depth of leaf nodes.
.tris
tris: Object
Min and max triangle count in leaf nodes.
.splits
splits: Array<number>
Number of splits on each axis as a three-element array [X, Y, Z].
getBVHExtremes
getBVHExtremes( bvh: MeshBVH ): Array<BVHExtremes>
Measures the min and max extremes of the BVH tree structure, including node depth, leaf primitive count, split axis distribution, and a surface-area heuristic score. Returns one entry per root group in the BVH.
estimateMemoryInBytes
estimateMemoryInBytes( bvh: BVH ): number
Roughly estimates the amount of memory in bytes used by a BVH by walking its object graph and summing typed-array byte lengths and primitive sizes.
validateBounds
validateBounds( bvh: MeshBVH ): boolean
Validates that every node's bounding box fully contains its children and,
for leaf nodes, fully contains all of its primitives. Uses console.assert
to log failures and returns false if any check fails.
getJSONStructure
getJSONStructure( bvh: BVH ): Object
Returns a plain-object tree that mirrors the BVH hierarchy, useful for
inspecting or serialising the structure for debugging. Each node has a
bounds (Box3) and either { count, offset } (leaf) or { left, right }
(internal) fields.