# BVHComputeData

class in `three-mesh-bvh/webgpu`

```js
import { BVHComputeData } from 'three-mesh-bvh/webgpu';
```

Packs one or more scene objects into GPU-accessible BVH buffers (TLAS + BLAS) for use
in WebGPU compute shaders via the Three.js TSL node system. After construction, call
`BVHComputeData#update` to populate the storage buffers, then reference
`this.storage` and `this.fns` in your compute shader nodes.

> **Note:** This API is unstable and subject to change in future releases.

> **Note:** This class requires three.js r185 or higher.

Example: Ray tracing a mesh's BVH in a compute shader

```js
import { Matrix4, Mesh, MeshBasicNodeMaterial, SRGBColorSpace, StorageTexture, TorusKnotGeometry } from 'three/webgpu';
import { colorSpaceToWorking, globalId, texture, textureStore, uniform, wgslFn } from 'three/tsl';
import { FullScreenQuad } from 'three/addons/postprocessing/Pass.js';
import { BVHComputeData, ndcToCameraRay } from 'three-mesh-bvh/webgpu';

// scene, camera and renderer are initialized here

const WORKGROUP_SIZE = [ 8, 8, 1 ];

const mesh = new Mesh( new TorusKnotGeometry( 1, 0.3, 300, 50 ) );
const bvhData = new BVHComputeData( mesh, { attributes: { position: 'vec4f', normal: 'vec4f' } } );
bvhData.update();

const outputTex = new StorageTexture( window.innerWidth, window.innerHeight );
const cameraToWorld = uniform( new Matrix4() );
const inverseProjection = uniform( new Matrix4() );

const raytrace = wgslFn( /* wgsl */`
	fn compute(
		outputTex: texture_storage_2d<rgba8unorm, write>,
		inverseProjectionMatrix: mat4x4f,
		cameraToWorldMatrix: mat4x4f,
		globalId: vec3u,
	) -> void {

		let dimensions = textureDimensions( outputTex );
		let uv = vec2f( globalId.xy ) / vec2f( dimensions );
		var ray = ndcToCameraRay( uv * 2.0 - vec2f( 1.0 ), cameraToWorldMatrix * inverseProjectionMatrix );

		var hit: IntersectionResult;
		bvh_RaycastFirstHit( ray, &hit );

		if ( hit.didHit ) {

			let normal = normalize( bvh_sampleTrianglePoint( hit.barycoord, hit.indices.xyz ).normal.xyz );
			textureStore( outputTex, globalId.xy, vec4f( normal, 1.0 ) );

		} else {

			textureStore( outputTex, globalId.xy, vec4f( 0.0366, 0.0813, 0.1057, 1.0 ) );

		}

	}
`, [ ndcToCameraRay, bvhData.fns.raycastFirstHit, bvhData.fns.sampleTrianglePoint ] );

const kernel = raytrace( {
	outputTex: textureStore( outputTex ),
	inverseProjectionMatrix: inverseProjection,
	cameraToWorldMatrix: cameraToWorld,
	globalId,
} ).computeKernel( WORKGROUP_SIZE );

const material = new MeshBasicNodeMaterial();
material.colorNode = colorSpaceToWorking( texture( outputTex ), SRGBColorSpace );
const quad = new FullScreenQuad( material );
const dispatchSize = [ Math.ceil( outputTex.width / 8 ), Math.ceil( outputTex.height / 8 ) ];

renderer.setAnimationLoop( () => {

	camera.updateMatrixWorld();
	cameraToWorld.value.copy( camera.matrixWorld );
	inverseProjection.value.copy( camera.projectionMatrixInverse );

	renderer.compute( kernel, dispatchSize );
	quad.render( renderer );

} );
```

## Constructor

```js
new BVHComputeData( objects: Object3D | BufferGeometry | GeometryBVH | Array, options?: Object )
```

- `objects`, `Object3D | BufferGeometry | GeometryBVH | Array`: Scene objects to include. A single item or array of Object3D, BufferGeometry, or GeometryBVH instances are
all accepted and wrapped automatically in a BVH.
- `options`, `Object`, optional
  - `attributes`, `Record<string, string>`, optional, default `{ position: 'vec4f' }`: WGSL type map for the interleaved per-vertex attribute buffer. Keys are geometry
attribute names; values are WGSL type strings (e.g. `'vec3f'`, `'vec4f'`).
  - `autogenerateBvh`, `boolean`, optional, default `true`: When true, a `MeshBVH` is automatically built for any object that does not
already have `geometry.boundsTree` set.

## Methods

### .getRootObject

```js
.getRootObject(  ): Object3D
```

Returns the representative root object for the scene to be constructed.

### .getShapecastFn

```js
.getShapecastFn( options: Object ): function
```

Builds a WGSL shapecast function that traverses the TLAS and per-cluster BLAS in a single
merged stack/loop for a custom shape type. The returned function signature is:
`fn name( shape: ShapeStruct[, result: ptr<function, ResultStruct>] ) -> bool`

- `options`, `Object`
  - `name`, `string`, optional: Function name. Defaults to a random identifier.
  - `shapeStruct`, `StructTypeNode`: TSL struct or definition describing the query shape.
  - `resultStruct`, `StructTypeNode | null`, optional: TSL struct for the accumulated result, or null.
  - `prefixFn`, `function | null`, optional: function node that runs before the bvh traversal - useful for resetting or initializing necessary module variables.
  - `boundsOrderFn`, `function | null`, optional: function node controlling left/right child traversal order.
  - `intersectsBoundsFn`, `function`: function node testing the shape against a BVH node's bounds.
  - `intersectRangeFn`, `function`: function node testing the shape against a leaf triangle range.
  - `transformShapeFn`, `function | null`, optional: function node that transforms the shape into object local space.
  - `transformResultFn`, `function | null`, optional: function node that transforms a hit result back to world space.
  - `resetShapeFn`, `function | null`, optional: function node called after each BLAS traversal to reset any per-object state set by `transformShapeFn`.

Returns `function`: TSL function node for the traversal.

### .update

```js
.update(  )
```

Rebuilds all GPU storage buffers from the current scene state. Must be called at least
once before using `this.storage` or `this.fns` in a shader, and again whenever the
scene topology changes (objects added/removed, geometry modified).

### .updateTransforms

```js
.updateTransforms(  )
```

Refits the clustered BVH and rewrites every entry in the transform buffer from the objects'
current world matrices. Call this when object transforms or visibility change but the scene
topology does not. The transform slots are derived from the clustered BVH's primitive buffer,
so they match those written by `BVHComputeData#update`.

### .dispose

```js
.dispose(  )
```

Releases GPU resources held by this instance.
