import { d } from './index'; /** * Gaussian radial falloff: `exp(-(dist² · sharpness))`. 1 at the centre, decaying smoothly with no * hard cutoff — the shape of a glare, a bloom core, or a soft light pool. * * `sharpness` is an inverse squared radius, not a radius: larger is TIGHTER. A light whose size is * authored as a radius should pass `1 / (r² + ε)`, which is why the callers that expose a size * slider compute their sharpness rather than passing the slider through. */ export declare const radialGaussianFalloff: import('typegpu').TgpuFn<(dist: d.F32, sharpness: d.F32) => d.F32>; /** * Gaussian falloff over an already-normalized 2D offset: `exp((du² + dv²) · -sharpness)`. * * "Normalized" means each axis has been divided by its own radius before the call, which is what * makes the spot ELLIPTICAL — pass `u/su, v/sv` with different radii and the falloff stretches along * the wider axis. Callers layering several spots at different sharpnesses over the same `du, dv` * (a core plus a wide shoulder) get the anisotropy for free. */ export declare const anisotropicGaussianSpot: import('typegpu').TgpuFn<(du: d.F32, dv: d.F32, sharpness: d.F32) => d.F32>; /** * A round glow at a point in aspect-corrected UV space: `exp(-0.5 · dist² / sizeSq)`. * * Takes the light position as loose scalars and `sizeSq` as a SQUARED radius because the callers * that place several of these per frame compute the positions and radii on the CPU (they are * pixel-invariant) and pass them in packed vec4 extraFields — squaring on the GPU would be per-pixel * work for a per-frame value. */ export declare const radialGaussianGlow: import('typegpu').TgpuFn<(uv: d.Vec2f, aspect: d.F32, lx: d.F32, ly: d.F32, sizeSq: d.F32) => d.F32>; /** * Rotating sine lobes around an angle: `pow(sin(angle · count + phase) · 0.5 + 0.5, sharpness)`. * * The `·0.5 + 0.5` before the `pow` is what makes this read as rays rather than alternating bands: * the sine's negative half becomes the gap between lobes, and raising the whole [0,1] wave to a * power narrows the bright part without moving the lobe centres. `sharpness` below 1 widens. * * `phase` is signed time in practice — NEGATE the accumulated time to rotate clockwise. */ export declare const angularSineLobes: import('typegpu').TgpuFn<(angle: d.F32, count: d.F32, phase: d.F32, sharpness: d.F32) => d.F32>; /** * Diffraction-style spikes around an angle: `pow(abs(cos(angle · halfCount)), power)`. * * `abs` (rather than the `·0.5 + 0.5` of {@link angularSineLobes}) is why this gives 2·halfCount * spikes with hard nulls between them, the signature of an aperture's blade count — pass * `blades / 2`. High `power` (3–8) is what makes them thin. Layering two calls at different powers * and a small angular offset is the standard way to get a primary/secondary spike pattern. */ export declare const angularCosineSpikes: import('typegpu').TgpuFn<(angle: d.F32, halfCount: d.F32, power: d.F32) => d.F32>; /** * Seam-free angular coordinates for a radial field, returned as * `vec3(angle, angleWrapped, blend)`. * * THE PROBLEM THIS SOLVES: `atan2` returns [−π, π], so any pattern periodic in the angle has a * discontinuity along the −x axis where the value jumps by 2π. Wrapping the angle into [0, 2π) * moves the seam but does not remove it. The fix is to evaluate the pattern TWICE — once on each * branch — and cross-fade between them across the seam, using a blend that is 0/1 well away from it. * A conditional branch instead of a blend puts the seam back. * * Callers evaluate their pattern at `.x` and `.y` and `mix(atWrapped, atAngle, .z)`. Both * evaluations must stay unconditional. */ export declare const seamlessAngularField: import('typegpu').TgpuFn<(delta: d.Vec2f) => d.Vec3f>; /** * Three concentric ring bands at radii `center + spread`, `center`, `center − spread`, returned as * an RGB triple — the prismatic edge of a lens element or a dispersed halo. * * Each channel is `1 − smoothstep(0, width, abs(dist − r))`, i.e. a band peaking ON its radius. The * red channel takes the OUTER radius by convention (longer wavelength refracts less), so a positive * `spread` gives the physically-expected red-outside/blue-inside fringe; pass a negative spread to * invert it. * * `width` is floored at 1e-4 because callers derive it from a size slider (LensFlare's ring width is * `size · 0.10`), and a zero width makes `smoothstep(0, 0, ·)` undefined. */ export declare const chromaticRingBand: import('typegpu').TgpuFn<(dist: d.F32, center: d.F32, spread: d.F32, width: d.F32) => d.Vec3f>; /** * Project a point onto a segment: returns `vec2(t, distance)` where `t` ∈ [0,1] is the clamped * parameter of the closest point along `a → b`. * * Returning BOTH values is the point — a tapered beam needs the parameter to interpolate its * thickness and the distance to shade its cross-section, and recomputing either costs the same as * the whole projection. The `max(lengthSq, 1e-4)` guard keeps a degenerate (zero-length) segment * finite rather than NaN, which matters because a UI lets both endpoints sit on the same pixel. */ export declare const pointToSegment: import('typegpu').TgpuFn<(p: d.Vec2f, a: d.Vec2f, b: d.Vec2f) => d.Vec2f>; /** * The glow cross-section of a tapered beam: given the perpendicular `dist` and the along-beam * parameter `t` from {@link pointToSegment}, interpolate thickness and softness end-to-end and * return `vec2(colorT, alpha)`. * * `alpha` is a smoothstep shoulder from the beam edge outward, raised to `1 + softness · 1.5` so a * soft beam does not merely get wider but also fades non-linearly — a linear ramp reads as a flat * band with a visible outer edge. `colorT` is the inside→outside colour parameter over the same * transition zone, so a caller can shade the core and the falloff differently. * * The interpolated softness is floored at 1e-4 for the same reason `thickness` is: the softness props * bottom out at 0 (Beam's do), and a zero softness collapses both transition zones to * `smoothstep(1, 1, ·)`, which is undefined. */ export declare const taperedSegmentGlow: import('typegpu').TgpuFn<(dist: d.F32, t: d.F32, startThickness: d.F32, endThickness: d.F32, startSoftness: d.F32, endSoftness: d.F32) => d.Vec2f>; /** * A single soft streak band across a 1D coordinate: `exp(-(u - center)² / width²)` — a Gaussian * band peaking at `center`, the shape of light bouncing between film and backing plate, an * anamorphic bar, or any parallel-band artifact. Multiply several at different centers/widths for * a band stack. */ export declare const streakBand: import('typegpu').TgpuFn<(u: d.F32, center: d.F32, width: d.F32) => d.F32>; /** * Overexposure colour ramp: fringe → mid → hot as `heat` rises, with the energy scaling by heat * (clamped at 1.6) so the fringe stays dim and the core blooms — the dye response of overexposed * film. Sample per-channel at offset heats for chromatic fringing ({@link chromaticHeatTaps}). */ export declare const heatRamp3: import('typegpu').TgpuFn<(heat: d.F32, hot: d.Vec3f, mid: d.Vec3f, fringe: d.Vec3f) => d.Vec3f>; /** * Three {@link heatRamp3} taps at offset heats (×1.08 / ×1 / ×0.88 for R/G/B) assembled into one * RGB — the chromatic fringing of an overexposed boundary, where the channels bloom at slightly * different rates. */ export declare const chromaticHeatTaps: import('typegpu').TgpuFn<(heat: d.F32, hot: d.Vec3f, mid: d.Vec3f, fringe: d.Vec3f) => d.Vec3f>; /** * The outer fade of a bounded radial light: 1 inside, smoothstepping to 0 between * `radius · (1 − feather)` and `radius`. `feather` is the fraction of the radius spent fading. */ export declare const radialFeatherMask: import('typegpu').TgpuFn<(dist: d.F32, radius: d.F32, feather: d.F32) => d.F32>; /** * {@link angularSineLobes} driven by a designer-facing `softness` slider: softness inverts into * the lobe exponent (`1 / (softness + 0.05) · 0.3`), so a soft ray is a low power, which widens * the bright part of each lobe without moving its centre. */ export declare const softRayLobes: import('typegpu').TgpuFn<(angle: d.F32, count: d.F32, phase: d.F32, softness: d.F32) => d.F32>; /** * Distance + angle around an unflipped centre prop, in aspect-corrected space: returns * `vec2(dist, angle)`. `center` is a TRANSFORMED position prop (stores `1 − y`), so this recovers * the authored y. The aspect is applied per-term (`uv.x·aspect − cx·aspect`) — the spelling the * radial light generators shipped with, kept verbatim. */ export declare const radialBurstFrame: import('typegpu').TgpuFn<(uv: d.Vec2f, viewport: d.Vec2f, center: d.Vec2f) => d.Vec2f>; /** * Quadratic corner-darkening mask about the frame centre: `clamp(1 − dist² · strength, 0, 1)` in * aspect-corrected space (aspect from the effective viewport, so a resize-fit box keeps the mask * round). 1 = untouched centre; strength 0 disables it. */ export declare const vignetteMask: import('typegpu').TgpuFn<(uv: d.Vec2f, viewport: d.Vec2f, strength: d.F32) => d.F32>; /** * Exposure composite of emitted light over a base colour: screen blend + an additive overexposure * push (×0.16) + the alpha raised by the light's Rec.601 luminance (×0.85) — emitted light shows * even over transparent areas. The film-exposure tail of a light leak or glow overlay. */ export declare const screenGlowComposite: import('typegpu').TgpuFn<(color: d.Vec4f, leakRgb: d.Vec3f) => d.Vec4f>; /** * The local frame of a beam anchored at a point and aimed at the canvas centre: returns * `vec2(u, v)` — distance ALONG the beam and LATERAL offset from it, in aspect-corrected space. * * `anchorRaw` is a TRANSFORMED position prop (`transformPosition` stores `1 − y`), so this recovers * the authored y itself. The direction degenerates when the anchor sits at the centre; below a 0.02 * length it falls back to +x rather than normalizing near-zero, which would make the frame spin * wildly as the anchor crosses the middle. * * Everything downstream (bloom, streak bands, falloff) is authored in this frame, which is what lets * a light leak be dragged anywhere on the canvas and still point inward. */ export declare const beamLocalFrame: import('typegpu').TgpuFn<(uv: d.Vec2f, aspect: d.F32, anchorRaw: d.Vec2f) => d.Vec2f>; //# sourceMappingURL=lightfields.d.ts.map