import { d } from '../kit'; /** * Plain Gaussian brush weight from a PRE-SQUARED distance and radius: `exp(-distSq / radiusSq)`. * * Peaks at 1 in the centre and never reaches zero — cells outside the nominal radius still receive * ~37% and below. This is what the fluid splats shipped with before the edge-shifted form existed; * it stays available because a few consumers deliberately want the long tail. * * `radiusSq` must already be guarded (`max(r*r, eps)`) by the caller — the grid-space consumers * clamp to one cell (`max(r*r, 1.0)`), which is a different floor than a UV-space consumer wants. */ export declare const gaussianBrushSq: import('typegpu').TgpuFn<(distSq: d.F32, radiusSq: d.F32) => d.F32>; /** * Edge-shifted Gaussian brush weight: `(exp(-distSq/radiusSq) - e⁻¹) / (1 - e⁻¹)`, clamped to * [0, 1]. * * Still exactly 1 at the centre, but falls to exactly 0 at `distSq == radiusSq` and is clamped flat * beyond it — no truncation step, no staircase. PixelThrow's CPU sim has had this since it shipped; * D-8 propagates it to the GPU brush sites. */ export declare const gaussianBrushShiftedSq: import('typegpu').TgpuFn<(distSq: d.F32, radiusSq: d.F32) => d.F32>; /** Vector form of {@link gaussianBrushSq} — takes the cell and brush centres. */ export declare const gaussianBrushRaw: import('typegpu').TgpuFn<(cellPos: d.Vec2f, center: d.Vec2f, radiusSq: d.F32) => d.F32>; /** Vector form of {@link gaussianBrushShiftedSq} — takes the cell and brush centres. */ export declare const gaussianBrushShifted: import('typegpu').TgpuFn<(cellPos: d.Vec2f, center: d.Vec2f, radiusSq: d.F32) => d.F32>; /** * The edge-shifted brush at a given TRUNCATION RADIUS, expressed in sigmas. * * `radiusSq` is always σ² — the Gaussian's own scale. `cutoffSigmas` is how far out the CALLER stops * evaluating, and it sets the edge constant to `exp(-cutoffSigmas²)` so the falloff reaches exactly * zero there and nowhere else. Get it wrong and the brush changes width, not just its edge: passing * a 3σ consumer the 1σ constant rescales the whole profile. * * Memoised per cutoff, and `$name`d per cutoff so two differently-truncated brushes in one tree do * not collide on a WGSL identifier. */ export declare function gaussianBrushShiftedSqFn(cutoffSigmas?: number): import('typegpu').TgpuFn<(distSq: d.F32, radiusSq: d.F32) => d.F32>; /** Vector form of {@link gaussianBrushShiftedSqFn} — takes the cell and brush centres. */ export declare function gaussianBrushShiftedFn(cutoffSigmas?: number): import('typegpu').TgpuFn<(cellPos: d.Vec2f, center: d.Vec2f, radiusSq: d.F32) => d.F32>; /** Which falloff a consumer wants. `edgeShift` is the corrected form and the recommended default. */ export interface GaussianBrushOptions { edgeShift: boolean; /** * Truncation radius in sigmas — where the caller stops evaluating the brush. Default 1 (the * fluid/PixelThrow case: cut at the radius the Gaussian is scaled by). Ignored when * `edgeShift` is false, since an unshifted brush has no edge constant. */ cutoffSigmas?: number; } /** * Pick the squared-distance brush fn for an option record — the form the fluid splat kernels use, * since they have already computed `dx`/`dy` for the spread/perpendicular maths and would otherwise * subtract twice. * * Structural (C5): `edgeShift` is read at composition time, so it costs nothing on the GPU. */ export declare function gaussianBrushFnSq(opts: GaussianBrushOptions): import('typegpu').TgpuFn<(distSq: d.F32, radiusSq: d.F32) => d.F32>; /** Pick the vector-form brush fn for an option record. See {@link gaussianBrushFnSq}. */ export declare function gaussianBrushFn(opts: GaussianBrushOptions): import('typegpu').TgpuFn<(cellPos: d.Vec2f, center: d.Vec2f, radiusSq: d.F32) => d.F32>; //# sourceMappingURL=simShared.d.ts.map