ComputeMeshSurfaceSampler
new ComputeMeshSurfaceSampler(mesh : THREE.Mesh, renderer : THREE.WebGPURenderer, count : number, options : MeshSurfaceSamplerOptions)GPU mesh surface sampler using TSL.
Overview This class implements a high-performance surface sampling algorithm that runs entirely on the GPU. It is designed to generate thousands or millions of instances distributed on the surface of a mesh.
Algorithm
- CPU Pre-processing: Builds a weighted distribution (CDF) and Alias Table based on triangle areas.
- GPU Sampling: Uses the Alias Method (O(1)) to select triangles and Blue Noise to pick barycentric coordinates.
- Output: Writes transformation matrices to a storage buffer, ready for
InstancedMesh.
Features
- Blue Noise: Ensures samples are well-distributed (low discrepancy) and temporally stable.
- Alias Method: Efficient O(1) selection of weighted triangles.
- Normal Alignment: Aligns instance Y-axis to the surface normal.
Example: Grass distribution on terrain
Example: Resampling specific instances
// Resample only instance 42 (e.g., for respawning)
await sampler.compute({ resampleIndex: 42 });
// Measure GPU performance
const timestamp = await sampler.compute({ trackTimestamp: true });
console.log(`Sampling took ${timestamp}ms`);
Constructor Parameters
meshTHREE.MeshSource mesh to sample from.
rendererTHREE.WebGPURendererWebGPU renderer instance.
countnumberNumber of samples/instances to generate.
optionsoptionalMeshSurfaceSamplerOptionsConfiguration options.
Example
import { ComputeMeshSurfaceSampler } from '@three-blocks/core';
import * as THREE from 'three/webgpu';
// Load terrain mesh
const terrain = await loadTerrain();
// Create sampler for 100,000 grass blades
const sampler = new ComputeMeshSurfaceSampler(terrain, renderer, 100000, {
seed: 42,
useVertexNormals: true
});
// Run sampling on GPU
await sampler.compute();
// Create instanced grass using the sampled transforms
const grassGeometry = new THREE.PlaneGeometry(0.1, 0.5);
const grassMaterial = new THREE.MeshStandardNodeMaterial({ color: 0x3d9140 });
const grass = new THREE.InstancedMesh(grassGeometry, grassMaterial, 100000);
// Assign the GPU-generated transforms directly
grass.instanceMatrix = sampler.output;
scene.add(grass);
Properties
# .renderer : THREE.WebGPURenderer
# .count : number
# .output :
Returns the GPU storage buffer containing instance transformation matrices. Can be directly assigned to InstancedMesh.instanceMatrix.
# .outputNormal :
Returns the GPU storage buffer containing world-space surface normals per instance.
Methods
compute#
compute(options : Object) : Promise<(number|undefined)>Recompute on GPU. Pass {resampleIndex} to update just one instance.
Parameters
optionsoptionalObjectOptions
resampleIndexoptionalnumberIf provided, updates only this instance index; otherwise all instances are recomputed.trackTimestampoptionalbooleanIf true, returns the GPU timestamp.
Returns
Promise<(number|undefined)> — GPU timestamp if {trackTimestamp} is true, otherwise null.readback#
readback() : Promise<Float32Array>(optional) Read back transformation matrices to CPU
Returns
Promise<Float32Array> — Array of mat4 matrices (16 floats per instance)