Skip to content

encode.webgpu.Class.GainMapEncoder

github-actions[bot] edited this page Oct 20, 2026 · 2 revisions

@monogrid/gainmap-js / encode/webgpu / GainMapEncoder

Class: GainMapEncoder

Defined in: src/encode/webgpu/GainMapEncoder.ts:121

Encodes an HDR image into an SDR rendition + a gain map, on the GPU, with TSL nodes.

GainMapEncoder.sdr and GainMapEncoder.gainMap are live texture nodes: every encoding parameter is a uniform, changing one re-renders the affected nodes once, when they're next used. No renderer is needed until the result is read back with GainMapEncoder.read or GainMapEncoder.compress.

Read back images are oriented top to bottom (like ImageData), no flipY is needed when compressing them.

Example

import { GainMapEncoder } from '@monogrid/gainmap-js/encode/webgpu'
import { encodeJPEGMetadata } from '@monogrid/gainmap-js/libultrahdr'
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js'
import { AgXToneMapping, MeshBasicNodeMaterial, WebGPURenderer } from 'three/webgpu'

const renderer = new WebGPURenderer()
await renderer.init()

const image = await new EXRLoader().loadAsync('image.exr')
const encoder = new GainMapEncoder(image, { toneMapping: AgXToneMapping })
// encode the full HDR range
await encoder.fitMaxContentBoost(renderer)

// live previews, they follow any parameter change
sdrMaterial.colorNode = encoder.sdr
gainMapMaterial.colorNode = encoder.gainMap
hdrMaterial.colorNode = encoder.createPreviewNode() // decodes the encoded result

encoder.sdr.exposure.value = 0.9
encoder.gainMap.gamma.value.setScalar(1.1)

// compress and embed into a single JPEG file
const result = await encoder.compress(renderer, { mimeType: 'image/jpeg', quality: 0.9 })
const jpeg = encodeJPEGMetadata(result)

Constructors

Constructor

new GainMapEncoder(image, options?): GainMapEncoder

Defined in: src/encode/webgpu/GainMapEncoder.ts:137

Parameters

image

DataTextureLoaderTexData | HDRInput

the HDR image: a texture, raw texture data (e.g. from a worker) or a TSL node (which requires width and height)

options?

GainMapEncoderOptions = {}

encoding parameters, all of them can be changed later through the node uniforms

Returns

GainMapEncoder

Properties

gainMap

readonly gainMap: GainMapEncoderNode

Defined in: src/encode/webgpu/GainMapEncoder.ts:129

The gain map node


sdr

readonly sdr: SDRRenditionNode

Defined in: src/encode/webgpu/GainMapEncoder.ts:125

The SDR rendition node

Accessors

height

Get Signature

get height(): number

Defined in: src/encode/webgpu/GainMapEncoder.ts:152

Height of the encoded images

Returns

number


metadata

Get Signature

get metadata(): GainMapMetadata

Defined in: src/encode/webgpu/GainMapEncoder.ts:157

The gain map metadata matching the current parameters

Returns

GainMapMetadata


width

Get Signature

get width(): number

Defined in: src/encode/webgpu/GainMapEncoder.ts:150

Width of the encoded images

Returns

number

Methods

compress()

compress(renderer, options): Promise<GainMapEncoderCompressedResult>

Defined in: src/encode/webgpu/GainMapEncoder.ts:249

Renders (if needed), reads back and compresses the SDR rendition and gain map

Parameters

renderer

WebGPURenderer

options

CompressOptions & object

compression options, flipY is not needed

Returns

Promise<GainMapEncoderCompressedResult>

Throws

if the browser does not support createImageBitmap


createPreviewNode()

createPreviewNode(): GainMapNode

Defined in: src/encode/webgpu/GainMapEncoder.ts:209

Creates a GainMapNode decoding the encoded result on the fly, it follows any change to the encoding parameters. Its maxDisplayBoost is initialized to restore the full HDR range, and is not changed afterwards.

Returns

GainMapNode


dispose()

dispose(): void

Defined in: src/encode/webgpu/GainMapEncoder.ts:271

Disposes the nodes, and the HDR texture if it was created by the encoder from raw data

Returns

void


fitContentBoost()

fitContentBoost(renderer): Promise<{ max: number; min: number; }>

Defined in: src/encode/webgpu/GainMapEncoder.ts:189

Finds the actual range of the per pixel gain between the HDR image and its current SDR rendition and uses it as minContentBoost / maxContentBoost, so that the gain map can restore the HDR image exactly.

Unlike GainMapEncoder.fitMaxContentBoost this takes the SDR rendition into account: tone mapping operators like Cineon, AgX or ACES make some pixels of the SDR rendition brighter (or less saturated) than the HDR image, which requires a minContentBoost below 1, and they compress highlights more than a plain clamp, which may require a maxContentBoost above the HDR max. Exposure, brightness, contrast and saturation have the same effect.

Call it again whenever the SDR rendition or the offsets change.

Parameters

renderer

WebGPURenderer

Returns

Promise<{ max: number; min: number; }>

the new minContentBoost and maxContentBoost


fitMaxContentBoost()

fitMaxContentBoost(renderer): Promise<number>

Defined in: src/encode/webgpu/GainMapEncoder.ts:168

Finds the max value of the HDR image and uses it as maxContentBoost, so the full HDR range is encoded.

Parameters

renderer

WebGPURenderer

Returns

Promise<number>

the new maxContentBoost


read()

read(renderer): Promise<GainMapEncoderRawResult>

Defined in: src/encode/webgpu/GainMapEncoder.ts:228

Renders (if needed) and reads back the raw SDR rendition and gain map

Parameters

renderer

WebGPURenderer

Returns

Promise<GainMapEncoderRawResult>


render()

render(renderer): void

Defined in: src/encode/webgpu/GainMapEncoder.ts:218

Renders the SDR rendition and the gain map, only if something changed since the last render

Parameters

renderer

WebGPURenderer

Returns

void

Clone this wiki locally