/** * @fileoverview GaussianDensify — adaptive density control for the native 3DGS trainer. * * The original 3DGS paper's Algorithm 1: gaussians whose accumulated screen-space (2D mean) gradient * exceeds a threshold are "under-reconstructed" and get densified — small ones are CLONED (a jittered * copy is added), large ones are SPLIT (replaced by two smaller ones sampled from their distribution). * Transparent gaussians (opacity below a floor) are PRUNED. This is how a sparse init grows into a * dense scene — the mechanism the 2026-06-20 /critic review correctly named as missing * ("fixed-cardinality trainer"). Now built, gated, and verified. * * Deterministic: all randomness comes from a seeded RNG the caller passes, so densification is * reproducible (and the count is assertable in tests). */ import { type Gaussian3D } from './GaussianTrainer3D'; /** Per-gaussian densification statistics accumulated over an interval by the runner. */ export interface DensifyStats { /** Average ||∂L/∂mean2d|| (screen-space, px) per gaussian over the interval. */ avgGrad2d: Float64Array; } export interface DensifyOpts { /** Densify gaussians whose avg 2D-mean gradient exceeds this (px). */ gradThreshold: number; /** Prune gaussians with opacity below this. */ opacityPrune: number; /** Clone if max world scale <= this, otherwise split. */ scaleThreshold: number; /** Split shrink factor (paper: φ = 1.6). */ splitFactor?: number; /** Hard cap on gaussian count (stop densifying when reached). */ maxGaussians: number; } export interface DensifyResult { gaussians: Gaussian3D; /** origin[newIdx] = source oldIdx for survivors, -1 for freshly created (clone/split) gaussians. * Lets the caller carry Adam moments for survivors and zero them for new ones. */ origin: Int32Array; } /** * Apply pruning + densification. Returns a new (resized) Gaussian3D and the origin map. Gaussian * count grows (clones/splits) and shrinks (prune); a fixed-cardinality run is what you get by simply * not calling this. */ export declare function densifyAndPrune(g: Gaussian3D, stats: DensifyStats, opts: DensifyOpts, rng: () => number): DensifyResult; /** Small seeded LCG so densification (and its tests) are deterministic. */ export declare function seededRng(seed: number): () => number; //# sourceMappingURL=GaussianDensify.d.ts.map