/** * The coarse evidence floor. * * A tilt grid blends four neighbouring stored views. When the pointer moves faster than those * views decode, the corners still in flight have no evidence at all, and the runtime is forced to * present whatever is still bound — a view several grid steps away, whose forward warp stretches * across depth discontinuities. Giving each corner a thumbnail of its OWN stored view removes that * choice: every corner always has evidence at the right pose, so nothing stale is ever presented. * * The atlas is one still image decoded once at load. It never reaches WebCodecs, holds no decoder * session, and consumes none of the admission budget — which is what makes it affordable, and what * distinguishes it from the paged delivery atlas that was removed. */ import * as THREE from 'three/webgpu'; import type { BakedMotionCoarse } from './BakedMotionManifest.cjs'; import type { TSLFloatNode, TSLUniformNode, TSLVec2Node, TSLVec4Node } from '../types/tsl.cjs'; /** Seconds a corner takes to dissolve from its thumbnail to its decoded self. */ export declare const BAKED_MOTION_COARSE_RAMP_SECONDS = 0.12; export interface BakedMotionCoarseTextures { readonly color: THREE.Texture; readonly depth: THREE.Texture | null; } export interface BakedMotionCoarseFloor { /** Per slot: 0 presents the thumbnail, 1 presents the decoded view, between dissolves. */ readonly presence: TSLUniformNode<'float', number>[]; /** Per slot: which stored view the thumbnail should show. */ readonly tile: TSLUniformNode<'int', number>[]; sampleColorSlot(slot: number, coordinate: TSLVec2Node): TSLVec4Node; sampleDepthSlot(slot: number, coordinate: TSLVec2Node): TSLFloatNode; /** Advance every ramp toward its target. Returns true while any slot is still dissolving. */ advance(deltaSeconds: number, targets: readonly number[]): boolean; residentBytes(): number; dispose(): void; } /** Both ImageBitmap uploads allocate RGBA textures, including the grayscale depth PNG. */ export declare function bakedMotionCoarseResidentBytes(coarse: BakedMotionCoarse): number; /** * Build the per-slot sampling graph over a decoded coarse atlas. * * Tile addressing is deliberately arithmetic on the frame index alone: the encoder packs frames in * sequence order, so tile column/row is `frame % columns` / `frame / columns` whatever the * package's grid order happens to be. No serpentine decode, no lookup table to fall out of sync. */ export declare function createBakedMotionCoarseFloor(coarse: BakedMotionCoarse, textures: BakedMotionCoarseTextures, slots: number): BakedMotionCoarseFloor; /** * Decode the coarse images into textures. Bytes arrive already fetched and digest-verified by the * caller, which owns the package's integrity discipline; a wrong or truncated atlas would silently * present the wrong views, so it is never used unverified. */ export declare function createBakedMotionCoarseTextures(albedo: ArrayBuffer, depth: ArrayBuffer | null): Promise;