import type { Box3, BufferGeometry, ComputeNode, Matrix4, Quaternion, Renderer, Storage3DTexture, Vector3 } from 'three/webgpu'; import type { GeometryBVH } from 'three-mesh-bvh' with { "resolution-mode": "import" }; import { type GeometryBVHComputeData } from './bvh/bvhComputeData.cjs'; import type { ComputeBVHSamplerSource } from './ComputeBVHSampler.cjs'; import type { TSLUniformNode } from '../types/tsl.cjs'; export interface ComputeSDFGeneratorOptions { resolution?: number | undefined; margin?: number | undefined; threshold?: number | undefined; bounds?: Box3 | null | undefined; workgroupSize?: Vector3 | undefined; } /** * GPU-accelerated SDF (Signed Distance Field) generator using mesh BVH. * * **Overview** * Generates a 3D texture containing signed distances from a mesh surface. * It uses a BVH (Bounding Volume Hierarchy) acceleration structure to efficiently query the closest point on the mesh for each voxel. * * **Features** * - **Fast Generation**: Uses compute shaders to generate SDFs in parallel. * - **BVH Acceleration**: Leverages `three-mesh-bvh` for O(log N) distance queries. * - **Dynamic Updates**: Can update the SDF if the mesh deforms (provided the BVH is updated). * * **Usage** * The generated 3D texture can be used for: * - **Volume Rendering**: Raymarching clouds, smoke, or fluids. * - **Collision Detection**: GPU-based particle collisions. * - **VFX**: Attracting/repelling particles from a surface. * * @example * import { GenerateMeshBVHWorker } from 'three-mesh-bvh/worker'; * import { ComputeSDFGenerator } from 'three-blocks/sdf-raymarching'; * * // 1. Generate BVH (async worker recommended) * const worker = new GenerateMeshBVHWorker(); * const bvh = await worker.generate(geometry, { targetLeafSize: 1 }); * * // 2. Create SDF Generator * const sdfGen = new ComputeSDFGenerator({ * resolution: 64, * margin: 0.2 * }); * * // 3. Generate SDF Texture * await sdfGen.generate(mesh, bvh, renderer); * const sdfTexture = sdfGen.sdfTexture; * * @class ComputeSDFGenerator * @short GPU SDF generator that builds a 3D distance texture from a mesh using a BVH. * @category Compute * @tags WebGPU */ export declare class ComputeSDFGenerator implements ComputeBVHSamplerSource { resolution: number; margin: number; threshold: number; customBounds: Box3 | null; workgroupSize: Vector3; _sdfTexture: Storage3DTexture | null; _boundsMatrix: Matrix4; _inverseBoundsMatrix: Matrix4; _bounds: Box3; _geometryBounds: Box3; _meshMatrixWorld: Matrix4; _boundsSize: Vector3; _boundsCenter: Vector3; _boundsQuaternion: Quaternion; _skinnedPositionArray: Float32Array | null; _skinnedPositionTarget: Vector3; _computeKernel: ComputeNode | null; _initialized: boolean; _uMatrix: TSLUniformNode<'mat4', Matrix4>; _uDim: TSLUniformNode<'uint', number>; _uThreshold: TSLUniformNode<'float', number>; _bvhData: GeometryBVHComputeData | null; /** * Create a new SDF generator. * * @param {Object} [options] - Configuration options. * @param {number} [options.resolution=64] - SDF grid resolution (resolution^3 voxels). Higher is more detailed but slower. * @param {number} [options.margin=0.2] - Extra margin around mesh bounds to capture the field. * @param {number} [options.threshold=0.0] - Distance threshold (bias) applied to the SDF. * @param {THREE.Box3} [options.bounds] - Custom bounds for the SDF volume. Auto-computed from geometry if not provided. * @param {THREE.Vector3} [options.workgroupSize=Vector3(4,4,4)] - Compute shader workgroup size. Tweak for performance. */ constructor(options?: ComputeSDFGeneratorOptions); /** * Generates SDF texture from mesh and BVH. * * @param {THREE.BufferGeometry} geometry - Source geometry * @param {*} bvh - BVH from three-mesh-bvh (with _roots array) * @param {THREE.WebGPURenderer} renderer - WebGPU renderer * @returns {Promise} Generated SDF texture */ generate(geometry: BufferGeometry, bvh: GeometryBVH, renderer: Renderer): Promise; /** * Updates SDF texture with potentially modified mesh/BVH. * More efficient than full regeneration if structure hasn't changed. * * @param {THREE.BufferGeometry} geometry - Source geometry * @param {*} bvh - BVH from three-mesh-bvh * @param {THREE.WebGPURenderer} renderer - WebGPU renderer * @returns {Promise} Updated SDF texture */ update(geometry: BufferGeometry, bvh: GeometryBVH, renderer: Renderer): Promise; /** * Computes bounding box with margin. * @private * @param {THREE.BufferGeometry} geometry */ _computeBounds(geometry: BufferGeometry): void; /** * Computes bounding box from skinned mesh positions. * Used for SkinnedMeshBVH where geometry.boundingBox is the bind pose. * @private * @param {Float32Array} positionArray - Current skinned vertex positions */ _computeSkinnedBounds(positionArray: Float32Array): void; /** * Initializes or recreates the Storage3DTexture. * @private */ _initializeTexture(): void; /** * Creates the compute shader for SDF generation. * @private * @param {GeometryBVHComputeData} bvhData * @returns {THREE.ComputeNode} */ _createComputeKernel(bvhData: GeometryBVHComputeData): ComputeNode; /** * Ensures vertex position data is Float32Array. * For SkinnedMeshBVH, extracts transformed positions from the skinned mesh. * @private * @param {THREE.BufferGeometry} geometry * @param {*} [bvh] - Optional BVH, used to detect SkinnedMeshBVH * @returns {Float32Array} */ _getPositionArray(geometry: BufferGeometry, bvh: GeometryBVH): Float32Array; /** * Gets the generated SDF texture. * @returns {THREE.Storage3DTexture | null} */ get sdfTexture(): Storage3DTexture | null; /** * Gets the bounds transformation matrix (local to world). * @returns {THREE.Matrix4} */ get boundsMatrix(): Matrix4; /** * Gets the inverse bounds matrix (world to local). * @returns {THREE.Matrix4} */ get inverseBoundsMatrix(): Matrix4; /** * Gets the computed bounding box (includes margin). * @returns {THREE.Box3} */ get bounds(): Box3; /** * Gets the tight geometry bounding box (without margin). * Useful for focused sampling in ComputeBVHSampler. * @returns {THREE.Box3} */ get geometryBounds(): Box3; /** * Gets the mesh's world matrix (for skinned meshes). * Used by ComputeBVHSampler to transform output to world space. * @returns {THREE.Matrix4} */ get meshMatrixWorld(): Matrix4; /** * Disposes GPU resources. */ dispose(): void; }