/**
 * 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<THREE.BufferGeometry, THREE.NodeMaterial> {
    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<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
    readonly shadowGeometry: THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
    /**
     * 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<THREE.BufferGeometry, THREE.NodeMaterial>;
    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;
    }>;
}
