/** * Strict, structured-clone-safe contracts for the Three Blocks shader cache. * * The artifact is a normalized cache snapshot: exact shader modules, node * addresses, binding layouts, and update/attribute plans are each stored once * in deterministic pools; states reference them by index. Capture tooling * writes version 3 manifests. The worker runtime consumes only a manifest that * the build marked fresh and a versioned Three.js adapter accepts. * * Before changing this contract, read docs/maintenance/shader-precompile-system.md; * the schema versions below are validated at three independent sites. */ export declare const PRECOMPILED_MANIFEST_VERSION: 3; export declare const SHADER_ADDRESS_SCHEMA_VERSION: 2; export declare const SHADER_RECIPE_SCHEMA_VERSION: 1; export declare const SHADER_HYDRATION_SCHEMA_VERSION: 2; export declare const THREE_WEBGPU_R185_COMPATIBILITY: "three-webgpu-r185-v1"; export declare const THREE_WEBGL_R185_COMPATIBILITY: "three-webgl-r185-v1"; export declare const THREE_WEBGPU_R186_COMPATIBILITY: "three-webgpu-r186-v1"; export declare const THREE_WEBGL_R186_COMPATIBILITY: "three-webgl-r186-v1"; export type ShaderStage = 'vertex' | 'fragment' | 'compute'; export type ShaderBuildKind = 'render' | 'compute'; export type ShaderBackend = 'webgpu' | 'webgl'; /** Seam identity for a released Three.js version; `undefined` when no seam verifies it. */ export declare function threeShaderCompatibilityId(threeVersion: string, backend: ShaderBackend): "three-webgpu-r185-v1" | "three-webgl-r185-v1" | "three-webgpu-r186-v1" | "three-webgl-r186-v1" | undefined; /** GLSL manifests differ from WGSL ones in validation and label identity, in every release. */ export declare function isWebGLShaderCompatibility(id: unknown): boolean; /** True for the identity of any released seam, independent of the installed version. */ export declare function isReleasedShaderCompatibility(value: unknown): value is string; export type ShaderRegistrationKind = 'material' | 'pipeline' | 'compute'; export type ShaderManifestState = 'fresh' | 'stale' | 'invalid' | 'missing' | 'not-observed'; export type ShaderPathSegment = string | number; export type SerializedShaderValue = null | boolean | number | string | readonly SerializedShaderValue[] | { readonly [key: string]: SerializedShaderValue; }; /** * A stable path to a live node. Recipe-backed variants are resolved exclusively by * the active, version-gated Three.js compatibility adapter. Typed-array payloads * inside `inputValue` records use little-endian base64 `data` strings. */ export type NodeAddress = { readonly k: 'anchor'; readonly key?: string; readonly slot: string; readonly path: readonly number[]; } | { readonly k: 'container'; readonly key: string; readonly path: readonly ShaderPathSegment[]; } | { readonly k: 'owned'; readonly owner: NodeAddress; readonly path: readonly ShaderPathSegment[]; readonly prime?: 'reference'; } | { readonly k: 'tsl'; readonly name: string; } | { readonly k: 'lightNode'; readonly light: number; /** Scene traversal fallback for render paths whose built LightsNode is empty. */ readonly sceneLight?: number; } | { readonly k: 'lightUniform'; readonly fn: 'lightPosition' | 'lightTargetPosition' | 'lightViewPosition' | 'lightShadowMatrix' | 'spotLightMap' | 'shadowCameraNear' | 'shadowCameraFar' | 'shadowBias' | 'shadowIntensity' | 'shadowNormalBias' | 'shadowRadius' | 'shadowBlurSamples' | 'shadowMapSize'; readonly light: number; /** Scene traversal fallback for render paths whose built LightsNode is empty. */ readonly sceneLight?: number; } | { readonly k: 'materialCache'; readonly property: string; readonly type: string | null; } | { readonly k: 'sceneEnv'; } | { readonly k: 'namedRenderUniform'; readonly name: string; } | { readonly k: 'reference'; readonly property: string; readonly uniformType: string; readonly count?: number; readonly object?: { readonly container: string; readonly path: readonly ShaderPathSegment[]; }; readonly group?: string; readonly name?: string; } | { readonly k: 'inputNode'; readonly nodeClass: string; readonly value: { readonly container: string; readonly path: readonly ShaderPathSegment[]; }; readonly access?: string | null; readonly uniformType?: string | null; readonly group?: string; /** Application-set node name; deterministic buffer labels derive from it. */ readonly name?: string; /** Whether TextureNode used a depth-comparison sampler in captured WGSL. */ readonly comparison?: boolean; /** Whether TextureNode was gathered: r186 declares a sampler for it even when unfilterable. */ readonly gather?: boolean; /** StorageBufferNode reconstruction metadata (ignored by other input recipes). */ readonly bufferCount?: number; readonly atomic?: boolean; readonly pbo?: boolean; /** BufferAttributeNode reconstruction metadata (ignored by other recipes). */ readonly stride?: number; readonly offset?: number; readonly usage?: number; readonly instanced?: boolean; readonly n?: number; } | { readonly k: 'inputValue'; readonly nodeClass: string; readonly json: SerializedShaderValue; readonly access?: string | null; readonly uniformType?: string | null; readonly group?: string; /** Application-set node name; deterministic buffer labels derive from it. */ readonly name?: string; readonly comparison?: boolean; readonly gather?: boolean; readonly bufferCount?: number; readonly atomic?: boolean; readonly pbo?: boolean; readonly stride?: number; readonly offset?: number; readonly usage?: number; readonly instanced?: boolean; readonly n?: number; } | { readonly k: 'recipe'; readonly id: string; readonly version: typeof SHADER_RECIPE_SCHEMA_VERSION; readonly input?: SerializedShaderValue; }; /** * One final unique uniform declaration: `[node, instance, type, stage, name]`. * * `node` indexes the manifest node pool. Rows sharing `(node, instance)` bind * one live node across stages; a higher `instance` marks a distinct live node * capture observed at the same semantic address — hydration clones it, in row * order. Instances are 0-based, contiguous, and first-occurrence ordered. */ export type PrecompiledDeclaration = readonly [ node: number, instance: number, type: string, stage: ShaderStage, name: string | null ]; export interface PrecompiledAttribute { readonly name: string; readonly type: string; /** Node pool index, or null for plain geometry attributes. */ readonly node: number | null; } export interface PrecompiledBinding { readonly name: string; readonly kind: string; /** Captured live storage access mode; hydration compares it structurally. */ readonly access?: string; /** Captured storage-texture flag for sampled-texture binding kinds. */ readonly store?: boolean; /** Exact member order for a NodeUniformsGroup's STD140 buffer. */ readonly uniforms?: readonly PrecompiledBindingUniform[]; } export interface PrecompiledBindingUniform { readonly name: string; readonly type: string; } export interface PrecompiledBindingGroup { readonly name: string; readonly bindings: readonly PrecompiledBinding[]; } export interface PrecompiledObserver { readonly hasNode: boolean; readonly hasAnimation: boolean; } /** * One hydratable NodeBuilderState record. All numeric fields index manifest * pools; the same state may serve several entry keys. */ export interface PrecompiledState { /** Module pool indexes per stage; compute states leave vertex/fragment null. */ readonly vertex: number | null; readonly fragment: number | null; readonly compute: number | null; readonly declarations: readonly PrecompiledDeclaration[]; /** Layout pool index. */ readonly layout: number; /** Attribute-plan pool index. */ readonly attributes: number; /** Update-plan pool indexes: [updateNodes, updateBeforeNodes, updateAfterNodes]. */ readonly updates: readonly [number, number, number]; /** Requirement-plan pool index; absent when the state needs no optional features. */ readonly requirements?: number; readonly observer: PrecompiledObserver | null; readonly hardwareClipping: boolean; } export interface PrecompiledRuntimeCompatibility { readonly id: string; readonly address: typeof SHADER_ADDRESS_SCHEMA_VERSION; readonly recipe: typeof SHADER_RECIPE_SCHEMA_VERSION; readonly hydration: typeof SHADER_HYDRATION_SCHEMA_VERSION; } export interface PrecompiledAutomaticRegistration { /** Capture-time prefix used for deterministic unregistered render/compute keys. */ readonly prefix: string; } /** * Version 3 shader artifact: deterministic pools plus integer references. * `three` and `runtime` are optional in the authored type so minimal status * artifacts can still be inspected; runtime injection rejects their absence * and safely builds live. */ export interface PrecompiledManifest { readonly version: typeof PRECOMPILED_MANIFEST_VERSION; readonly scene: string; readonly three?: string; readonly threeBlocks?: string; readonly runtime?: PrecompiledRuntimeCompatibility; readonly automatic?: PrecompiledAutomaticRegistration; /** False opts into direct hydration; release parity must certify it. Absent means true. */ readonly requiresSetup?: boolean; /** Exact whole-program WGSL sources — the same identity `Pipelines` interns by. */ readonly modules: readonly string[]; /** Deduplicated node addresses referenced by declarations and plans. */ readonly nodes: readonly NodeAddress[]; readonly layouts: readonly (readonly PrecompiledBindingGroup[])[]; readonly attributePlans: readonly (readonly PrecompiledAttribute[])[]; /** Node pool indexes per update list. */ readonly updatePlans: readonly (readonly number[])[]; /** Required optional WebGPU features per requirement plan. */ readonly requirementPlans: readonly (readonly string[])[]; readonly states: readonly PrecompiledState[]; /** Stable application key to state pool index. */ readonly entries: Readonly>; /** Registered states intentionally left on the live backend path, keyed like `entries`. */ readonly fallbacks?: Readonly>; } /** Build kind of one pooled state. */ export declare function stateKind(state: Pick): ShaderBuildKind; export interface ShaderBuildState { readonly state: ShaderManifestState; /** * `'live'` over a fresh receipt is a choice, not a failure: the development default, * where every edit strands the receipt. It installs the live observer without a warning * and never trips `strict`. Absent or `'precompiled'` follows `state`. */ readonly mode?: 'precompiled' | 'live'; readonly strict?: boolean; /** Key-level changes when the Vite dependency graph can identify them safely. */ readonly changedKeys?: readonly string[]; readonly reason?: string; /** * The bundle was captured when its build closed. No receipt describes it: the manifest * is build output at `three-blocks/shaders/..json`, loaded from * there instead of through `loadManifest`, and its absence means the scene compiles live. */ readonly built?: { readonly base: string; }; } export interface ShaderAnchor { readonly slot: string; readonly node: ShaderNodeLike; } export interface ShaderNodeChild { readonly childNode: ShaderNodeLike; } /** Deliberately small structural view of a Three.js node. */ export interface ShaderNodeLike { readonly isNode?: boolean; id?: number; getSerializeChildren?(): Iterable; } export interface ShaderRenderObjectLike { readonly material: object; readonly object: object; readonly scene?: object | null; readonly lightsNode?: ShaderNodeLike | null; } export interface ShaderBindingLike { readonly name: string; readonly kind?: string; readonly constructor?: { readonly name?: string; }; readonly uniforms?: readonly ShaderUniformBindingLike[]; } export interface ShaderUniformBindingLike { readonly name: string; getType?(): unknown; } export interface ShaderBindingGroupLike { readonly name: string; readonly bindings: readonly ShaderBindingLike[]; } export interface ShaderBindingBuilder { material?: object | null; scene?: object | null; lightsNode?: ShaderNodeLike | null; shaderStage?: ShaderStage | null; context?: Record; getUniformFromNode(node: ShaderNodeLike, type: string, stage: ShaderStage, name: string | null): unknown; sortBindingGroups(): void; getBindings(): readonly ShaderBindingGroupLike[]; } export interface ShaderAddressContext { readonly sceneKey: string; readonly key: string; readonly kind: ShaderBuildKind; readonly renderer: object; /** Active Three.js RenderObject for render builds; absent for compute builds. */ readonly renderObject?: object; readonly target: object; readonly object: object; readonly material: object | null; readonly scene: object | null; readonly lightsNode: ShaderNodeLike | null; readonly anchors: readonly ShaderAnchor[]; readonly container: (key: string) => object | undefined; builder?: ShaderBindingBuilder; } export interface HydratedBuilderState { readonly vertexShader: string | null; readonly fragmentShader: string | null; readonly computeShader: string | null; readonly attributes: readonly unknown[]; readonly bindings: readonly ShaderBindingGroupLike[]; readonly updateNodes: readonly ShaderNodeLike[]; readonly updateBeforeNodes: readonly ShaderNodeLike[]; readonly updateAfterNodes: readonly ShaderNodeLike[]; readonly observer: unknown; readonly hardwareClipping: boolean; readonly transforms: readonly unknown[]; } /** Tuple consumed by the r185 provider hook installed by `three-blocks/vite`. */ export type BuilderStateTuple = readonly [ vertexShader: string | null, fragmentShader: string | null, computeShader: string | null, attributes: readonly unknown[], bindings: readonly ShaderBindingGroupLike[], updateNodes: readonly ShaderNodeLike[], updateBeforeNodes: readonly ShaderNodeLike[], updateAfterNodes: readonly ShaderNodeLike[], observer: unknown, hardwareClipping: boolean, transforms: readonly unknown[] ]; export interface ShaderNodeBuilderStateConstructor { new (...state: BuilderStateTuple): object; } export interface ShaderProviderHook { getForRender(renderObject: ShaderRenderObjectLike): BuilderStateTuple | null; getForRender(renderObject: ShaderRenderObjectLike, NodeBuilderState: ShaderNodeBuilderStateConstructor, prepareForHydration?: () => void): object | null; getForCompute(computeNode: object): BuilderStateTuple | null; getForCompute(computeNode: object, NodeBuilderState: ShaderNodeBuilderStateConstructor, prepareForHydration?: () => void): object | null; } /** All Three.js-private behavior is centralized behind this versioned adapter. */ export interface ShaderCompatibility { readonly id: string; readonly threeVersion: string; supportsManifest(manifest: PrecompiledManifest): boolean; supportsRenderer(renderer: object): boolean; hasFeature?(renderer: object, feature: string): boolean; /** Return a reason when this backend must leave one captured state on the live path. */ unsupportedState?(state: PrecompiledState, manifest: PrecompiledManifest): string | null; anchorsFor(target: object, kind: ShaderBuildKind): readonly ShaderAnchor[]; createBindingBuilder(context: ShaderAddressContext): ShaderBindingBuilder; /** Finalize binding groups without colliding with another hydrated shader layout. */ getBindings?(builder: ShaderBindingBuilder, context: ShaderAddressContext): readonly ShaderBindingGroupLike[]; resolveRecipeAddress(address: Exclude, context: ShaderAddressContext): ShaderNodeLike; /** Materialize object state that Three normally creates after precompiled setup begins. */ primePrecompiledObject?(object: object): void; primeOwnedAddress?(node: ShaderNodeLike, context: ShaderAddressContext): void; primeBindingNode?(node: ShaderNodeLike, builder: ShaderBindingBuilder): void; /** Materialize a distinct binding node when capture observed multiple node identities at one semantic address. */ cloneBindingNode?(node: ShaderNodeLike, address: NodeAddress, instance: number, context: ShaderAddressContext): ShaderNodeLike; createAttribute?(name: string, type: string, node: ShaderNodeLike | null, builder: ShaderBindingBuilder): unknown; createObserver?(observer: PrecompiledObserver | null, context: ShaderAddressContext): unknown; bindingKind?(binding: ShaderBindingLike): string; installProvider(renderer: object, provider: ShaderProviderHook): () => void; } export interface ShaderCoverage { readonly registered: number; readonly registeredRender: number; readonly registeredCompute: number; readonly manifest: number; readonly manifestRender: number; readonly manifestCompute: number; readonly covered: number; readonly coveredRender: number; readonly coveredCompute: number; readonly missing: readonly string[]; readonly extra: readonly string[]; } export interface ShaderRuntimeStats extends ShaderCoverage { /** Number of times transformed Three.js consulted this provider. */ readonly lookups: number; readonly renderLookups: number; readonly computeLookups: number; readonly injected: number; readonly injectedRender: number; readonly injectedCompute: number; readonly missed: number; readonly missedRender: number; readonly missedCompute: number; readonly live: number; readonly liveRender: number; readonly liveCompute: number; readonly invalidated: number; readonly hydrationFailures: number; /** Total synchronous declaration/binding replay time. */ readonly hydrationMs: number; /** Longest single synchronous declaration/binding replay call. */ readonly maxHydrationMs: number; }