import { type Node, type NodeFrame, Texture, type TextureNode, type UniformNode, Vector3, type WebGPURenderer } from 'three/webgpu'; import { type GainMapMetadata } from '../../../core/types'; import { RenderTargetNode } from '../../../core/webgpu/RenderTargetNode'; /** * Textures and uniforms driving a {@link GainMapNode} decode */ export type GainMapNodeUniforms = { sdr: TextureNode; gainMap: TextureNode; gamma: UniformNode<'vec3', Vector3>; offsetSdr: UniformNode<'vec3', Vector3>; offsetHdr: UniformNode<'vec3', Vector3>; gainMapMin: UniformNode<'vec3', Vector3>; gainMapMax: UniformNode<'vec3', Vector3>; hdrCapacityMin: UniformNode<'float', number>; hdrCapacityMax: UniformNode<'float', number>; maxDisplayBoost: UniformNode<'float', number>; }; /** * A TSL texture node holding the HDR image decoded from an SDR image + gain map. * * The decode runs on the GPU into a HalfFloat render target, and only when something changed * (textures loaded/swapped or any uniform value changed): sampling the node costs a single * texture read, like any other texture. * * The node updates itself before rendering whenever it is part of a rendered node graph * (material, `scene.backgroundNode`, ...). When only its texture is used (`node.value`, * e.g. `scene.environment = node.value`) call {@link GainMapNode.decode} yourself. * * Re-decoding also flags the texture for PMREM regeneration, * so environment maps are recomputed only when the image actually changes. * * `node.value` gets its final size once loaded: three.js PMREMs don't follow texture resizes, * so assign it to `scene.environment` (or `pmremTexture()`) after load. * * @category Nodes * @group Nodes * * @example * import { GainMapNode } from '@monogrid/gainmap-js/webgpu' * import { equirectUV } from 'three/tsl' * * const hdr = new GainMapNode() * .setTextures(sdrTexture, gainMapTexture) * .setMetadata(metadata) * * material.colorNode = hdr * scene.backgroundNode = hdr.sample(equirectUV()) * hdr.maxDisplayBoost.value = 2 // re-decodes once, on the next frame */ export declare class GainMapNode extends RenderTargetNode { static get type(): string; /** * Shared textures and uniforms */ readonly uniforms: GainMapNodeUniforms; private _sdrSource; private _gainMapSource; constructor(); /** The SDR rendition texture (sRGB) */ get sdr(): Texture; /** The gain map recovery texture (linear) */ get gainMap(): Texture; /** @see {@link GainMapMetadata.gamma} */ get gamma(): UniformNode<"vec3", Vector3>; /** @see {@link GainMapMetadata.offsetSdr} */ get offsetSdr(): UniformNode<"vec3", Vector3>; /** @see {@link GainMapMetadata.offsetHdr} */ get offsetHdr(): UniformNode<"vec3", Vector3>; /** @see {@link GainMapMetadata.gainMapMin} */ get gainMapMin(): UniformNode<"vec3", Vector3>; /** @see {@link GainMapMetadata.gainMapMax} */ get gainMapMax(): UniformNode<"vec3", Vector3>; /** @see {@link GainMapMetadata.hdrCapacityMin} */ get hdrCapacityMin(): UniformNode<"float", number>; /** @see {@link GainMapMetadata.hdrCapacityMax} */ get hdrCapacityMax(): UniformNode<"float", number>; /** * @see {@link GainmapDecodingParameters.maxDisplayBoost} * @remarks Non Logarithmic space */ get maxDisplayBoost(): UniformNode<"float", number>; /** Width of the SDR image, 0 until loaded */ get width(): number; /** Height of the SDR image, 0 until loaded */ get height(): number; /** * Sets the SDR and gain map textures. * The SDR texture is expected in sRGB color space, the gain map in linear. * * Render target nodes (e.g. the `sdr` and `gainMap` nodes of a `GainMapEncoder`) are accepted as well: * they are rendered before decoding and the image is decoded again whenever they change. * * @param sdr * @param gainMap */ setTextures(sdr: Texture | RenderTargetNode, gainMap: Texture | RenderTargetNode): this; /** * Copies the gain map metadata into the uniforms. * Also sets `maxDisplayBoost` to fully restore the HDR range. * * @param metadata */ setMetadata(metadata: GainMapMetadata): this; protected _getState(): number[]; protected _getDependencies(): RenderTargetNode[]; protected _onRender(): void; /** * Decodes the image into {@link GainMapNode.renderTarget}, only if something changed since the last decode. * * Called automatically when the node is part of a rendered node graph. * * @param renderer * @returns `true` if the image was decoded */ decode(renderer: WebGPURenderer): boolean; /** * Calls {@link GainMapNode.decode} once per render, before the node is evaluated. * * @param frame */ updateBefore(frame: NodeFrame): undefined; /** * Disposes the render target, the SDR and gain map textures * (unless they belong to other render target nodes) */ dispose(): void; } /** * TSL function creating a {@link GainMapNode} from an SDR texture, a gain map texture and its metadata * * @param sdr * @param gainMap * @param metadata */ export declare const gainMapNode: (sdr: Texture, gainMap: Texture, metadata: GainMapMetadata) => GainMapNode & Node;