import type { Box3, ComputeNode, Matrix4, Renderer, Storage3DTexture, StorageInstancedBufferAttribute, Vector3 } from 'three/webgpu'; import type { TSLUniformNode } from '../types/tsl.js'; /** * Complete caller-owned SDF state consumed by {@link ComputeBVHSampler}. * * The sampler reads these values during construction, kernel replacement, and * every compute dispatch. Implementations may expose live mutable objects, but * the sampler never takes ownership of them. */ export interface ComputeBVHSamplerSource { /** Generated volume texture; construction fails while it is unavailable. */ readonly sdfTexture: Storage3DTexture | null; /** Local normalized-volume coordinates transformed into source-local space. */ readonly boundsMatrix: Matrix4; /** Source-local coordinates transformed into normalized-volume space. */ readonly inverseBoundsMatrix: Matrix4; /** Tight source-local geometry bounds used to focus rejection sampling. */ readonly geometryBounds: Box3; /** Source-local coordinates transformed into world space. */ readonly meshMatrixWorld: Matrix4; /** Cubic voxel dimension used to calculate texture coordinates. */ readonly resolution: number; } /** Sampling distributions exposed by {@link ComputeBVHSampler}. */ export type ComputeBVHSamplerStrategy = 'uniform' | 'surface' | 'custom'; export interface ComputeBVHSamplerOptions { strategy?: ComputeBVHSamplerStrategy | undefined; sdfThreshold?: number | undefined; seed?: number | undefined; maxAttempts?: number | undefined; surfaceWeight?: number | undefined; alignToNormal?: boolean | undefined; scale?: Vector3 | undefined; } export interface ComputeBVHSamplerComputeOptions { sdfThreshold?: number | undefined; debug?: boolean | undefined; } /** * GPU-accelerated point sampler for SDF volumes. * * **Architecture** * - Uses a pre-computed SDF (Signed Distance Field) to efficiently test volume containment. * - Employs **Blue Noise Sampling** for temporally stable, low-discrepancy point distribution. * - Supports **Rejection Sampling** on the GPU to conform to complex shapes. * - Outputs transformation matrices directly compatible with `THREE.InstancedMesh`. * * **Sampling Strategies** * - **Uniform**: Distributes points uniformly within the volume. * - **Surface**: (Planned) Distributes points near the surface. * - **Custom**: (Planned) Uses a custom density function. * * **Usage** * This class accepts any caller-owned source that satisfies * {@link ComputeBVHSamplerSource}; `ComputeSDFGenerator` is one implementation. * * @example * import { ComputeSDFGenerator } from 'three-blocks/sdf-raymarching'; * import { ComputeBVHSampler } from 'three-blocks'; * import * as THREE from 'three/webgpu'; * * // 1. Generate SDF from geometry * const sdfGen = new ComputeSDFGenerator({ resolution: 64 }); * await sdfGen.generate(geometry, bvh, renderer); * * // 2. Sample points inside the volume * const sampler = new ComputeBVHSampler(sdfGen, renderer, 10000, { * strategy: 'uniform', * sdfThreshold: 0.0, // < 0 is inside * samplingBounds: sdfGen.geometryBounds, // Tight bounds for efficiency * maxAttempts: 32, // Retry limit for rejection sampling * alignToNormal: true // Align instances to SDF gradient * }); * * // 3. Run compute shader * await sampler.compute(); * * // 4. Use output with InstancedMesh * const instancedMesh = new THREE.InstancedMesh(geometry, material, 10000); * instancedMesh.instanceMatrix = sampler.output; * * @class ComputeBVHSampler * @short GPU sampler that rejects/accepts points inside an SDF volume and outputs instance matrices or positions. * @category Compute * @tags WebGPU * @see {@link ComputeSDFGenerator} */ export declare class ComputeBVHSampler { sdfGenerator: ComputeBVHSamplerSource; renderer: Renderer; count: number; strategy: ComputeBVHSamplerStrategy; alignToNormal: boolean; samplingBounds: Box3 | null; uSeed: TSLUniformNode<'uint', number>; uThreshold: TSLUniformNode<'float', number>; uMaxAttempts: TSLUniformNode<'int', number>; uSurfaceWeight: TSLUniformNode<'float', number>; uInverseBoundsMatrix: TSLUniformNode<'mat4', Matrix4>; uBoundsMatrix: TSLUniformNode<'mat4', Matrix4>; uTexelSize: TSLUniformNode<'vec3', Vector3>; uSdfResolution: TSLUniformNode<'vec3', Vector3>; uScale: TSLUniformNode<'vec3', Vector3>; uSamplingMin: TSLUniformNode<'vec3', Vector3>; uSamplingMax: TSLUniformNode<'vec3', Vector3>; outMatrixSSBO: StorageInstancedBufferAttribute; outPositionsSSBO: StorageInstancedBufferAttribute; computeNode: ComputeNode | null; _compiled: boolean; /** * Create a new BVH-based volume sampler. * * @param {ComputeBVHSamplerSource} sdfGenerator - Caller-owned SDF texture, transforms, bounds, and resolution. * @param {THREE.WebGPURenderer} renderer - WebGPU renderer instance. * @param {number} count - Total number of samples to generate. * @param {Object} [options] - Configuration options. * @param {string} [options.strategy='uniform'] - Distribution strategy: `'uniform'`, `'surface'`, or `'custom'`. * @param {number} [options.sdfThreshold=0.0] - SDF value threshold. Points with distance < threshold are accepted. * - Negative values are inside the mesh. * - Positive values are outside (for shells). * @param {number} [options.seed=1337] - Random seed for stable sampling. * @param {number} [options.maxAttempts=32] - Maximum rejection sampling attempts per instance per frame. * @param {number} [options.surfaceWeight=1.0] - Weight for surface-weighted sampling (when strategy='surface'). * @param {boolean} [options.alignToNormal=false] - If true, aligns the Y-axis of instances to the SDF gradient (surface normal). * @param {THREE.Vector3} [options.scale=Vector3(1,1,1)] - Scale factor applied to each generated instance. */ constructor(sdfGenerator: ComputeBVHSamplerSource, renderer: Renderer, count: number, options?: ComputeBVHSamplerOptions); /** * Builds the compute shader for volume sampling. * Uses TSL Fn() to avoid ptr parameters which Safari/Firefox reject. * @private */ _buildComputeShader(): void; /** * Computes the volume sampling. * * @param {Object} [options] - Compute options * @param {number} [options.sdfThreshold] - Override SDF threshold * @param {boolean} [options.debug=false] - Enable debug logging * @returns {Promise} */ compute(options?: ComputeBVHSamplerComputeOptions): void; /** * Updates the SDF generator reference (useful when SDF is regenerated). * * @param {ComputeBVHSamplerSource} sdfGenerator - New caller-owned SDF source. */ updateSDF(sdfGenerator: ComputeBVHSamplerSource): void; /** * Gets the output transformation matrices. * @returns {THREE.StorageInstancedBufferAttribute} */ get output(): StorageInstancedBufferAttribute; /** * Gets the output positions buffer (vec3 per sample). * Useful for particle systems like SPH that only need positions. * @returns {THREE.StorageInstancedBufferAttribute} */ get positionsBuffer(): StorageInstancedBufferAttribute; /** * Performs CPU readback of transformation matrices. * @returns {Promise} */ readback(): Promise; readbackPositions(): Promise; /** * Calculates the valid sample rate (non-zero positions). * Accounts for potential vec4 padding in GPU buffers. * @param {Float32Array} positions - Positions array from readbackPositions() * @returns {number} Valid sample percentage (0-100) */ calculateValidRate(positions: Float32Array): number; /** * Disposes GPU resources. */ dispose(): void; }