import type { Effect, Frame, Gpu, Target } from "vgpu"; import type { ShaderName } from "./registry.js"; import { type SourceLayer } from "./source.js"; import type { Stage } from "./stage.js"; import type { ResolvedUniforms } from "./types.js"; /** * The render graph a graph shader draws through. * * The Stage owns the frame loop, so a graph splits along the seam the Stage * already has: `encode` runs every internal pass inside `prepare`, and * `present` is the ordinary full-screen effect the Stage draws into the * surface afterwards — same command buffer, same ordering, and the shared * `Params` post chain on the way out. * * Eight flavours share this shape. The particle graphs (ported from the vgpu * `fft-ocean` example) draw a displacement field as additive points into an * HDR scene; the drafting graphs measure a source layer, build a distance * field from its ink and draw it up as a plate; the glow graphs draw one * scene pass of light on dark; studio graphs render meshes and ray-traced * glass with depth of field; masonry graphs draw instanced slabs; landscapes * combine terrain, trees and grass; dielectric graphs layer a backdrop and * ray-marched glass. These share the bloom chain and present pass. Miniature * graphs instead finish with a tilt-shift blur over the rendered scene. */ export interface ShaderGraph { /** The final pass; the Stage binds `params` and draws it like any shader. */ readonly present: Effect; /** Encodes every internal pass into the frame, ahead of the present pass. */ encode(frame: Frame, uniforms: ResolvedUniforms, deltaTime: number): void; resize(width: number, height: number): void; /** Pre-warms every internal pipeline, so the first frame is not a stall. */ compile(): Promise; /** Loads image resources before the first draw, including shader swaps. */ load?(): Promise; destroy(): void; /** * Points the passes that read a layer at it. Only a graph whose flavour * reads a source has one; the renderer asks before it binds. */ bindSource?(layer: SourceLayer): void; } export declare function createGraph(stage: Stage, name: ShaderName, width: number, height: number): ShaderGraph; interface BloomTuning { readonly threshold: number; readonly smoothWidth: number; readonly strength: number; readonly radius: number; readonly kernelRadii: readonly [number, number, number, number, number]; readonly factors: readonly [number, number, number, number, number]; /** Which fragment entry gates the scene into the chain. */ readonly bright: "fs_bright" | "fs_brightAlpha"; } interface BloomChain { /** The recombined bloom the present pass adds to the scene. */ readonly output: Target; /** Rebuilds the half-resolution targets for a new scene and screen size. */ rebind(scene: Target, size: readonly [number, number]): void; /** Scales the chain's strength this frame — a control, not a constant. */ setStrength(multiplier: number): void; encode(frame: Frame): void; compile(): Promise[]; destroy(): void; } /** * The UnrealBloomPass chain from the example: a threshold gate into five * blurred octaves, recombined with per-level factors. It owns its own * half-and-down targets and rebuilds them whenever the scene it reads moves. */ export declare function createBloomChain(gpu: Gpu, source: string, label: string, scene: Target, tuning: BloomTuning): BloomChain; export {}; //# sourceMappingURL=graph.d.ts.map