import { Expr, GpuFragmentParams, KitTexture } from '../../gpu/contract'; import { d } from '../../gpu/kit/index'; import { RttFilterParams } from '../../gpu/scaffolds/rttFilter'; import { GatherEffect } from '../types'; import { PropRef } from '../values'; /** A stage that reads the layer inside (rendered to a texture) and gives one value per pixel. */ export type GatherStage = (params: RttFilterParams) => Expr; /** * A sample position that drifts slowly past hard edges, so paint bleeds instead of stopping. * * `amount` scales the drift in logical pixels (about four pixels per unit; 0 turns it off). * Build it once and pass the same stage as `at` to both `kuwahara` and `wash`, so the brush and * the original sample agree. * * @example * ```ts * const wet = bleedWarp({amount: p('bleed')}) * ``` * @tip Give the `amount` prop `recompile: crosses(0)` so turning the bleed off removes the work. * @see kuwahara, wash */ export declare function bleedWarp(slots: { amount: PropRef; }): GatherStage; /** The brush `kuwahara` builds: four overlapping patches of samples around each pixel. Pass it to `wash`. */ export type KuwaharaBrush = (params: RttFilterParams) => { quadrants: { sum: Expr; sq: Expr; }[]; invN: number; }; /** * A painter's brush: the flattening that turns fine detail into soft patches of one color. * * `radius` is the brush size in logical pixels, 1 to 8, and must be a compile-time prop. `at` * is the sample position, normally the same `bleedWarp` stage you hand to `wash`. Returns the * brush for `wash`. * * @example * ```ts * brush: kuwahara({at: wet, radius: p('radius')}) * ``` * @tip Mark `radius` `compileTime: true`. A hidden prop with a fixed default is the usual choice. * @see wash, bleedWarp */ export declare function kuwahara(slots: { at: GatherStage; radius: PropRef; }): KuwaharaBrush; /** * Fine paper grain for the pigment to settle into, one brightness value per screen pixel. * * `amount` runs 0 to 1; at 0 the grain is left out entirely. Returns the stage for the `grain` * slot of `wash`. Pass the same prop as `paper` there too. * * @example * ```ts * grain: paperGrain({amount: p('paper')}) * ``` * @tip Give the `amount` prop `recompile: crosses(0)`. * @see wash */ export declare function paperGrain(slots: { amount: PropRef; }): GatherStage; /** * The watercolor look: the layer inside flattened into soft patches of color over paper grain. * * Closes the recipe and returns the effect for `effect:`. `strength` runs from 0 (the original) * to 1 (the full wash). `paper` (0 to 1) sets how much grain shows and how far the result tints * toward `paperColor`. `at`, `brush` and `grain` are the stages from `bleedWarp`, `kuwahara` * and `paperGrain`. * * @example * ```ts * effect: wash({at: wet, brush: kuwahara({at: wet, radius: p('radius')}), grain: paperGrain({amount: p('paper')}), paper: p('paper'), paperColor: p('paperColor'), strength: p('strength')}) * ``` * @tip `strength` at 0 skips the whole effect. Give the prop `recompile: crosses(0)`. * @see kuwahara, bleedWarp, paperGrain */ export declare function wash(slots: { at: GatherStage; brush: KuwaharaBrush; grain: GatherStage; paper: PropRef; paperColor: PropRef; strength: PropRef; }): GatherEffect; /** The ring of edge samples `sobelTaps` builds around each pixel. Pass it to `chalkSketch`. */ export type SobelRing = (params: RttFilterParams) => { sobelA: Expr; sobelB: Expr; centre: Expr; centreLum: Expr; }; /** * Eight brightness samples in a ring around each pixel, for finding edges. * * `spacing` is the distance to the ring in device pixels (about 0.5 to 4; thicker strokes at * larger values). Returns the ring for `chalkSketch`. * * @example * ```ts * edges: sobelTaps({spacing: p('edgeThickness')}) * ``` * @see chalkSketch */ export declare function sobelTaps(slots: { spacing: PropRef; }): SobelRing; /** * The chalk-drawing look: edges become chalk strokes and dark areas fill with cross-hatching. * * Closes the recipe and returns the effect for `effect:`. `sensitivity` (0 to 1) sets how faint * an edge still draws. `hatchScale` is the hatch line spacing in device pixels. `shading` (0 to * 1) is how much cross-hatch fills the dark regions and `grain` (0 to 1) how dusty the strokes * are. `board` and `chalk` are colors. Alpha follows the layer inside. * * @example * ```ts * effect: chalkSketch({edges: sobelTaps({spacing: p('edgeThickness')}), sensitivity: p('edgeSensitivity'), hatchScale: p('hatchScale'), shading: p('shading'), grain: p('grain'), board: p('boardColor'), chalk: p('chalkColor')}) * ``` * @see sobelTaps, linework */ export declare function chalkSketch(slots: { edges: SobelRing; sensitivity: PropRef; hatchScale: PropRef; shading: PropRef; grain: PropRef; board: PropRef; chalk: PropRef; }): GatherEffect; /** A stage of the ASCII look: one value per pixel, computed in the fragment. */ export type FragmentStage = (params: GpuFragmentParams) => Expr; /** * The character grid: which cell each pixel falls in, and where it sits inside that cell. * * `cellSize` is the cell size in pixels on a 1080-pixel-tall canvas; it scales with the canvas * height. `spacing` is how much of the cell the character fills (1 fills it). Build it once and * share it with `cellSample`, `glyphFor` and `glyphTint`. * * @example * ```ts * const grid = charGrid({cellSize: p('cellSize'), spacing: p('spacing')}) * ``` * @see cellSample, glyphFor, glyphTint */ export declare function charGrid(slots: { cellSize: PropRef; spacing: PropRef; }): FragmentStage; /** * The color of the layer inside at the centre of each character cell. * * One sample per cell, straight alpha. Feeds `glyphFor` (to pick the character) and `glyphTint` * (to color it). * * @example * ```ts * const cell = cellSample({grid}) * ``` * @see charGrid, glyphFor */ export declare function cellSample(slots: { grid: FragmentStage; }): FragmentStage; /** * The character drawn in each cell, picked by how bright the cell is. * * `gamma` bends the brightness curve: below 1 favours the light characters, above 1 the dark * ones. `atlas` is your function that draws the character set into a texture and returns it * (the Ascii shader shows one). The definition needs three extra fields the atlas fills in: * `_charCount`, `_atlasScale` and `_atlasSize`. * * @example * ```ts * glyph: glyphFor({grid, cell, gamma: p('gamma'), atlas: setupGlyphAtlas}) * ``` * @see glyphTint, cellSample */ export declare function glyphFor(slots: { grid: FragmentStage; cell: FragmentStage; gamma: PropRef; atlas: (params: GpuFragmentParams) => KitTexture; }): FragmentStage; /** * The finished ASCII look: each character tinted with its cell's color, everything else transparent. * * Returns the fragment for `gpu.fragment`. Cells whose alpha is below `alphaThreshold` (0 to 1) * turn transparent. With `preserveAlpha` on, the output keeps the alpha of the layer inside; * off, visible characters are fully opaque. * * @example * ```ts * gpu: {fragment: glyphTint({grid, cell, glyph, alphaThreshold: p('alphaThreshold'), preserveAlpha: p('preserveAlpha')})} * ``` * @see glyphFor, charGrid */ export declare function glyphTint(slots: { grid: FragmentStage; cell: FragmentStage; glyph: FragmentStage; alphaThreshold: PropRef; preserveAlpha: PropRef; }): FragmentStage; /** @internal The oriented-box placement kernel behind the Text shader. */ export declare const orientedBoxField: import('typegpu').TgpuFn<(uv: d.Vec2f, aspect: d.F32, center: d.Vec2f, rotationDeg: d.F32, halfW: d.F32, halfH: d.F32) => d.Vec3f>; /** @internal One hatched line plate of the engraving; `linework` is the word. */ export declare const hatchPlate: import('typegpu').TgpuFn<(p: d.Vec2f, angleDeg: d.F32, frequency: d.F32, reliefPhase: d.F32, level: d.F32, aa: d.F32) => d.F32>; /** @internal The spiral plate of the engraving; `linework` is the word. */ export declare const spiralPlate: import('typegpu').TgpuFn<(p: d.Vec2f, c: d.Vec2f, frequency: d.F32, reliefPhase: d.F32, level: d.F32, aa: d.F32) => d.F32>; /** @internal The per-style engraving composite factory behind `linework`. */ export declare function makeLineworkComposite(style: number): import('typegpu').TgpuFn<(childColor: d.Vec4f, uv: d.Vec2f, aspect: d.F32, paper: d.Vec4f, ink: d.Vec4f, center: d.Vec2f, p0: d.Vec4f, p1: d.Vec4f) => d.Vec4f>; /** * The engraving look: the layer inside redrawn as ink lines that swell where it is dark. * * Closes the recipe and returns the effect for `effect:`. `style` is a compile-time select: * `'line'` (one set of parallel lines), `'crosshatch'` (more sets appear in the shadows) or * `'spiral'` (one line coiling out from `center`, a position prop). `frequency` is how many * lines span the canvas height. `angle` is in degrees. `relief` (0 to 2) is how far brightness * pushes the lines sideways, `waviness` (0 to 1) how much they meander, and `contrast` (0.25 to * 3) the tone curve before inking. `ink` and `paper` are colors. * * @example * ```ts * effect: linework({style: p('style'), frequency: p('frequency'), angle: p('angle'), center: p('center'), relief: p('relief'), waviness: p('waviness'), contrast: p('contrast'), ink: p('inkColor'), paper: p('paperColor')}) * ``` * @tip Set `blendWithChildren: false` on the definition. The lines replace the layer rather than sit on it. * @see chalkSketch */ export declare function linework(slots: { style: PropRef; frequency: PropRef; angle: PropRef; center: PropRef; relief: PropRef; waviness: PropRef; contrast: PropRef; ink: PropRef; paper: PropRef; }): GatherEffect; //# sourceMappingURL=stylize.d.ts.map