import type { Box3, BufferGeometry, ComputeNode, Matrix4, Renderer, Storage3DTexture, StorageBufferAttribute, Vector3 } from 'three/webgpu'; import type { PointsBVH } from 'three-mesh-bvh' with { "resolution-mode": "import" }; import type { TSLUniformNode } from '../types/tsl.cjs'; export type PointsSDFShellRadius = number | 'auto'; export interface ComputePointsSDFGeneratorOptions { resolution?: number | undefined; margin?: number | undefined; threshold?: number | undefined; shellRadius?: PointsSDFShellRadius | undefined; shellVoxels?: number | undefined; bounds?: Box3 | null | undefined; workgroupSize?: Vector3 | undefined; fillInterior?: boolean | undefined; } /** * GPU-accelerated SDF (Signed Distance Field) generator for point clouds using PointsBVH. * * **Overview** * Generates a 3D texture containing distances from a point cloud surface. * Uses PointsBVH (from three-mesh-bvh) for O(log N) nearest-point queries. * The "surface" is defined by a shell radius around each point. * * **Features** * - **Fast Generation**: Uses compute shaders to generate SDFs in parallel. * - **PointsBVH Acceleration**: Leverages `three-mesh-bvh` PointsBVH for efficient queries. * - **Shell Radius**: Defines surface thickness around points (auto-computed or user-specified). * - **Auto Shell Radius**: Estimates optimal radius from point cloud density. * * **Usage** * The generated 3D texture can be used for: * - **Volume Rendering**: Raymarching point cloud isosurfaces. * - **Collision Detection**: GPU-based particle collisions. * - **VFX**: Distance-based effects around point cloud surfaces. * * @example * import { PointsBVH } from 'three-mesh-bvh'; * import { ComputePointsSDFGenerator } from 'three-blocks/sdf-raymarching'; * * // 1. Build PointsBVH * const geometry = new THREE.BufferGeometry(); * geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); * geometry.computeBoundsTree({ type: PointsBVH }); * * // 2. Create SDF Generator * const sdfGen = new ComputePointsSDFGenerator({ * resolution: 64, * margin: 0.2, * shellRadius: 'auto' // or specific value like 0.05 * }); * * // 3. Generate SDF Texture * await sdfGen.generate(geometry, geometry.boundsTree, renderer); * const sdfTexture = sdfGen.sdfTexture; * * @class ComputePointsSDFGenerator * @short GPU SDF generator that builds a 3D distance texture from a point cloud using PointsBVH. * @category Compute * @tags WebGPU, PointCloud */ export declare class ComputePointsSDFGenerator { /** Cubic voxel resolution of the generated SDF texture. */ resolution: number; /** Fractional padding added around the source point bounds. */ margin: number; /** Signed-distance bias applied to generated samples. */ threshold: number; /** Requested point-shell radius, or automatic density-based selection. */ shellRadiusOption: PointsSDFShellRadius; /** Minimum automatic shell thickness measured in voxels. */ shellVoxels: number; _shellRadius: number; /** Optional caller-provided world-space SDF bounds. */ customBounds: Box3 | null; /** Compute workgroup dimensions used by the generation kernels. */ workgroupSize: Vector3; /** Whether enclosed regions are flood-filled into a signed solid. */ fillInterior: boolean; _sdfTexture: Storage3DTexture | null; _regionTexture: Storage3DTexture | null; _seedKernel: ComputeNode | null; _propagateKernel: ComputeNode | null; _applyKernel: ComputeNode | null; _boundsMatrix: Matrix4; _inverseBoundsMatrix: Matrix4; _bounds: Box3; _geometryBounds: Box3; _computeKernel: ComputeNode | null; _initialized: boolean; _uMatrix: TSLUniformNode<'mat4', Matrix4>; _uDim: TSLUniformNode<'uint', number>; _uThreshold: TSLUniformNode<'float', number>; _uShellRadius: TSLUniformNode<'float', number>; _geomIndex: StorageBufferAttribute | undefined; _geomPosition: StorageBufferAttribute | undefined; _bvhNodes: StorageBufferAttribute | undefined; /** * Create a new point cloud 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 point cloud bounds to capture the field. * @param {number} [options.threshold=0.0] - Distance threshold (bias) applied to the SDF. * @param {number|'auto'} [options.shellRadius='auto'] - Surface thickness around points. 'auto' estimates from point density. * @param {number} [options.shellVoxels=1.25] - Minimum auto shell radius in voxels so the surface survives grid sampling. * @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. * @param {boolean} [options.fillInterior=true] - Flood-fill sign the enclosed interior so the field is a solid * body instead of a hollow crust. Required for thickness-based effects (translucency, occupancy queries). */ constructor(options?: ComputePointsSDFGeneratorOptions); /** * Generates SDF texture from point cloud geometry and PointsBVH. * * @param {THREE.BufferGeometry} geometry - Source geometry with position attribute * @param {PointsBVH} bvh - PointsBVH from three-mesh-bvh * @param {THREE.WebGPURenderer} renderer - WebGPU renderer * @returns {Promise} Generated SDF texture */ generate(geometry: BufferGeometry, bvh: PointsBVH, renderer: Renderer): Promise; /** * Updates SDF texture with potentially modified point cloud/BVH. * More efficient than full regeneration if structure hasn't changed. * * @param {THREE.BufferGeometry} geometry - Source geometry * @param {PointsBVH} bvh - PointsBVH from three-mesh-bvh * @param {THREE.WebGPURenderer} renderer - WebGPU renderer * @returns {Promise} Updated SDF texture */ update(geometry: BufferGeometry, bvh: PointsBVH, renderer: Renderer): Promise; /** * Computes shell radius from point cloud density. * Uses BVH nearest-neighbor queries plus a voxel-aware lower bound. The lower * bound is important for point shells: a radius thinner than one voxel can fall * entirely between samples and produce an empty raymarched surface. * @private * @param {THREE.BufferGeometry} geometry * @param {PointsBVH} bvh */ _computeShellRadius(geometry: BufferGeometry, bvh: PointsBVH | null): void; /** * Computes bounding box with margin. * @private * @param {THREE.BufferGeometry} geometry */ _computeBounds(geometry: BufferGeometry): void; /** * Initializes or recreates the Storage3DTexture. * @private */ _initializeTexture(): void; /** * Builds the flood-fill signing kernels. Outside-connectivity floods from the * volume boundary through positive voxels (the crust blocks it); positive * voxels the flood never reaches are enclosed, and their distance is flipped * negative so the field describes a solid body. * @private */ _buildFloodKernels(): void; /** * Builds the compute shader for SDF generation from point cloud. * @private * @param {THREE.BufferGeometry} geometry * @param {PointsBVH} bvh */ _buildComputeShader(geometry: BufferGeometry, bvh: PointsBVH): void; /** * Updates geometry buffers (for dynamic point clouds). * @private * @param {THREE.BufferGeometry} geometry * @param {PointsBVH} bvh */ _updateGeometryBuffers(geometry: BufferGeometry, bvh: PointsBVH): void; /** * Gets or generates index array for the geometry. * For PointsBVH, indices are single uint values (one per point). * PointsBVH uses _indirectBuffer for primitive ordering (unlike MeshBVH which modifies geometry.index). * @private * @param {THREE.BufferGeometry} geometry * @param {PointsBVH} bvh * @returns {Uint32Array} */ _getIndexArray(geometry: BufferGeometry, bvh: PointsBVH | null): Uint32Array; /** * Generates sequential indices for non-indexed geometry. * @private * @param {THREE.BufferGeometry} geometry * @returns {Uint32Array} */ _generateIndices(geometry: BufferGeometry): Uint32Array; /** * Ensures vertex position data is Float32Array. * @private * @param {THREE.BufferGeometry} geometry * @returns {Float32Array} */ _getPositionArray(geometry: BufferGeometry): Float32Array; /** * Gets the generated SDF texture. * @returns {THREE.Storage3DTexture | null} */ get sdfTexture(): Storage3DTexture | null; /** * Gets the computed shell radius. * @returns {number} */ get shellRadius(): number; /** * Sets the shell radius (triggers regeneration on next generate call). * @param {number|'auto'} value */ set shellRadius(value: PointsSDFShellRadius); /** * 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). * @returns {THREE.Box3} */ get geometryBounds(): Box3; /** * Disposes GPU resources. */ dispose(): void; }