/** * A renderable set of instances of one preprocessed mesh (a three.js Mesh, so it goes into any scene). * * The geometry and instances live in a GeometryPool shared with other meshes; the pool's compute passes select * the cut for all of its meshes at once (see GeometryPool). This object holds the material and two geometries, * the camera cut and the shadow cut, which draw this mesh's region of the pool's index buffers. */ import * as THREE from 'three/webgpu'; import type { VirtualMeshData } from '../preprocess/buildVirtualMesh.js'; import type { VirtualGeometry } from './VirtualGeometry.js'; import { type GeometryPool, type PoolEntry } from './GeometryPool.js'; export { vgWorldNormal, vgInstanceOrigin, encodeOctNormal, packVertices, packUvs } from './GeometryPool.js'; export interface VirtualMeshInstances { /** 16 floats (column-major Matrix4) per instance. */ matrices: Float32Array; /** Optional rgba tint per instance (multiplied with the material color). */ colors?: Float32Array; } export interface VirtualMeshOptions { /** * Cull distance in world units: instances farther than this are not drawn (and cost almost nothing, since * whole cells are rejected at once). They shrink to nothing over the last 15% of the distance, so there is * no visible pop. Default: Infinity. Can be changed later via `mesh.maxDrawDistance`. */ maxDrawDistance?: number; /** * Hide instances whose bounding sphere is smaller than this many pixels (radius) on screen. Combined with * `VirtualGeometry.minPixelRadius` (the larger one wins). Default: 0. Also settable via `mesh.minPixelRadius`. */ minPixelRadius?: number; /** * Moves vertices in the vertex shader, e.g. foliage swaying in the wind: gets the world-space position node and * returns a displaced one (three.js TSL). `instanceOrigin` is the instance's world position, so a tree can bend * from its base. Culling and level of detail use the undisplaced geometry, so keep the displacement small (well * under a metre). */ deform?: (worldPosition: any, context: { instanceOrigin: any; }) => any; /** @deprecated Draw capacity is shared per pool now: see `VirtualGeometryOptions`. Ignored. */ maxDrawnMeshlets?: number; /** @deprecated Draw capacity is shared per pool now: see `VirtualGeometryOptions`. Ignored. */ maxDrawnTriangles?: number; } export declare class VirtualMesh extends THREE.Mesh { readonly isVirtualMesh = true; readonly data: VirtualMeshData; readonly instanceCount: number; readonly fullDetailTriangles: number; /** The pool holding this mesh's geometry and instances, and its record there. Set by `VirtualGeometry`. */ pool: GeometryPool; entry: PoolEntry; /** * Geometries drawing this mesh's region of the pool's camera and shadow index buffers: the meshlets drawn over * every pixel. Those inside an LOD blend band are drawn by `blendPart`. */ readonly cameraGeometry: THREE.BufferGeometry; readonly shadowGeometry: THREE.BufferGeometry; /** * Child mesh drawing the meshlets inside an LOD blend band (see lodBlend.ts), with a copy of the material that * keeps only the fragments of each pixel's own level. Kept apart because a shader that may discard fragments * loses early depth testing, which would slow down every other meshlet. */ readonly blendPart: THREE.Mesh; private readonly cameraBlendGeometry; private readonly shadowBlendGeometry; private blendSourceVersion; /** `context.frameCount` of the last shadow-map render of this mesh. */ lastShadowFrame: number; /** * Lever: draw this mesh into the occlusion depth pass, so it can hide other geometry. Default: solid * materials (opaque, single-sided, no alpha test). Foliage is mostly holes, so it only gets tested. */ occluder: boolean; /** Lever: let occlusion culling remove hidden instances and meshlets of this mesh. */ occlusionCulling: boolean; /** GPU instance slot of each caller instance (inverse of the Morton order). */ readonly gpuIndexOf: Uint32Array; /** Morton order: caller instance of each GPU slot. */ readonly gpuToInput: Uint32Array; private readonly dirtyCells; private drawingShadow; private poolVersion; /** The material's own MRT output, and whether the velocity output is merged into it (see setVelocityOutput). */ private readonly ownMrt; private velocityOutput; /** `options.deform`, applied to the pool's position node. */ private readonly deform; private readonly context; /** Cull distance in world units (Infinity: never). See `VirtualMeshOptions.maxDrawDistance`. */ get maxDrawDistance(): number; set maxDrawDistance(distance: number); /** Per-mesh minimum on-screen radius in pixels. See `VirtualMeshOptions.minPixelRadius`. */ get minPixelRadius(): number; set minPixelRadius(pixels: number); /** The pool's per-frame draw capacity (shared by every mesh of the pool). */ get capacity(): { meshlets: number; triangles: number; }; constructor(context: VirtualGeometry, data: VirtualMeshData, material: THREE.NodeMaterial, instances: VirtualMeshInstances, options?: VirtualMeshOptions); /** * Keeps the blend part's material and flags in step with this mesh (called by VirtualGeometry every frame): values * such as colours, maps and uniforms are copied each frame; a material change that needs a recompile (its version * changed, or a different material) is copied as a whole. */ syncBlendPart(): void; /** Points the geometries and the material at the pool's current buffers and nodes (after a pool rebuild). */ syncPool(): void; /** * Outputs the motion of the pulled vertices as `velocity` (for TAA), merged into the material's own MRT. Only * while a pass asks for it: a material MRT in a render target without MRT would replace the color output. */ setVelocityOutput(on: boolean): void; /** Force the next `VirtualGeometry.update` to recompute the cut. */ markCutDirty(): void; /** Update one instance transform. Call `commitInstances()` after a batch of changes. */ setMatrixAt(index: number, matrix: THREE.Matrix4): void; commitInstances(): void; /** * Stop rendering this mesh and drop it from its context. The GPU buffers are released when the * renderer frees them; call this before removing the object from the scene for good. */ dispose(context?: VirtualGeometry): void; /** Triangles drawn for this mesh by the last computed cut (camera and shadow), from one readback. */ readStats(renderer: THREE.WebGPURenderer): Promise<{ drawnTriangles: number; shadowTriangles: number; }>; }