@realsee/hdr-toolbox 1.0.3 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +41 -1
- package/dist/cli.js.map +1 -1
- package/dist/convert.d.ts +64 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +157 -0
- package/dist/convert.js.map +1 -0
- package/dist/exr.d.ts +26 -0
- package/dist/exr.d.ts.map +1 -0
- package/dist/exr.js +291 -0
- package/dist/exr.js.map +1 -0
- package/dist/hdr.d.ts +6 -0
- package/dist/hdr.d.ts.map +1 -0
- package/dist/hdr.js +263 -0
- package/dist/hdr.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/tonemap.d.ts +46 -0
- package/dist/tonemap.d.ts.map +1 -0
- package/dist/tonemap.js +369 -0
- package/dist/tonemap.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDR tone mapping operators for building the Ultra HDR base image.
|
|
3
|
+
*
|
|
4
|
+
* - `exposureFusion`: an implicit local tone map that synthesises several
|
|
5
|
+
* virtual exposures from the HDR and blends them with Mertens exposure fusion
|
|
6
|
+
* over a Laplacian pyramid. It keeps shadow and highlight detail at once and
|
|
7
|
+
* stays spatially smooth (no halos), which also keeps the derived gain map
|
|
8
|
+
* easy to compress.
|
|
9
|
+
* - `acesSdr` / `agxSdr`: global filmic curves ported from three.js, each with
|
|
10
|
+
* an automatic middle-grey exposure so bright scenes do not blow out.
|
|
11
|
+
* - `reinhardSdr`: a cheap global luminance-driven Reinhard curve.
|
|
12
|
+
*
|
|
13
|
+
* All return interleaved 8-bit sRGB RGB (3 channels), ready to be the Ultra HDR
|
|
14
|
+
* SDR base; the gain map is derived from this quantised base by the caller.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Global Reinhard tone map, luminance-driven. Compresses `luminance/(1+luminance)`
|
|
18
|
+
* and scales chroma by the same factor so hue and saturation survive.
|
|
19
|
+
* Returns interleaved 8-bit sRGB.
|
|
20
|
+
*/
|
|
21
|
+
export declare function reinhardSdr(data: Float32Array, width: number, height: number): Buffer;
|
|
22
|
+
/**
|
|
23
|
+
* ACES Filmic tone map, ported from three.js (includes its subjective 1/0.6
|
|
24
|
+
* brightening). High contrast, cinematic highlight shoulder. Applied per pixel
|
|
25
|
+
* after an automatic middle-grey exposure.
|
|
26
|
+
*/
|
|
27
|
+
export declare function acesSdr(data: Float32Array, width: number, height: number): Buffer;
|
|
28
|
+
/**
|
|
29
|
+
* AgX tone map (Filament/Blender fit), ported from three.js. Gentle, neutral
|
|
30
|
+
* highlight roll-off with low clipping. Applied per pixel after an automatic
|
|
31
|
+
* middle-grey exposure.
|
|
32
|
+
*/
|
|
33
|
+
export declare function agxSdr(data: Float32Array, width: number, height: number): Buffer;
|
|
34
|
+
export interface ExposureFusionOptions {
|
|
35
|
+
/** Spacing between synthetic exposures, in stops (default 2). */
|
|
36
|
+
evStep?: number;
|
|
37
|
+
/** Number of synthetic exposures, odd (default 5). */
|
|
38
|
+
exposureCount?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Exposure fusion tone map. Synthesises `exposureCount` exposures around an
|
|
42
|
+
* auto middle-grey EV0, blends them with Mertens weights over a Laplacian
|
|
43
|
+
* pyramid, and returns interleaved 8-bit sRGB RGB.
|
|
44
|
+
*/
|
|
45
|
+
export declare function exposureFusion(data: Float32Array, width: number, height: number, options?: ExposureFusionOptions): Buffer;
|
|
46
|
+
//# sourceMappingURL=tonemap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonemap.d.ts","sourceRoot":"","sources":["../src/tonemap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAerF;AAqDD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAkBjF;AAwCD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA6BhF;AAqID,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAmER"}
|
package/dist/tonemap.js
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDR tone mapping operators for building the Ultra HDR base image.
|
|
3
|
+
*
|
|
4
|
+
* - `exposureFusion`: an implicit local tone map that synthesises several
|
|
5
|
+
* virtual exposures from the HDR and blends them with Mertens exposure fusion
|
|
6
|
+
* over a Laplacian pyramid. It keeps shadow and highlight detail at once and
|
|
7
|
+
* stays spatially smooth (no halos), which also keeps the derived gain map
|
|
8
|
+
* easy to compress.
|
|
9
|
+
* - `acesSdr` / `agxSdr`: global filmic curves ported from three.js, each with
|
|
10
|
+
* an automatic middle-grey exposure so bright scenes do not blow out.
|
|
11
|
+
* - `reinhardSdr`: a cheap global luminance-driven Reinhard curve.
|
|
12
|
+
*
|
|
13
|
+
* All return interleaved 8-bit sRGB RGB (3 channels), ready to be the Ultra HDR
|
|
14
|
+
* SDR base; the gain map is derived from this quantised base by the caller.
|
|
15
|
+
*/
|
|
16
|
+
const clamp01 = (v) => (v < 0 ? 0 : v > 1 ? 1 : v);
|
|
17
|
+
/** Encode linear light (0-1) to an sRGB value (0-1). */
|
|
18
|
+
function linearToSrgb(value) {
|
|
19
|
+
const c = clamp01(value);
|
|
20
|
+
return c <= 0.0031308 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055;
|
|
21
|
+
}
|
|
22
|
+
/** Rec. 709 relative luminance. */
|
|
23
|
+
function luminance(r, g, b) {
|
|
24
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Global Reinhard tone map, luminance-driven. Compresses `luminance/(1+luminance)`
|
|
28
|
+
* and scales chroma by the same factor so hue and saturation survive.
|
|
29
|
+
* Returns interleaved 8-bit sRGB.
|
|
30
|
+
*/
|
|
31
|
+
export function reinhardSdr(data, width, height) {
|
|
32
|
+
const out = Buffer.alloc(width * height * 3);
|
|
33
|
+
for (let pixel = 0; pixel < width * height; pixel++) {
|
|
34
|
+
const base = pixel * 3;
|
|
35
|
+
const r = Math.max(0, data[base]);
|
|
36
|
+
const g = Math.max(0, data[base + 1]);
|
|
37
|
+
const b = Math.max(0, data[base + 2]);
|
|
38
|
+
const y = luminance(r, g, b);
|
|
39
|
+
const ySdr = y / (1 + y);
|
|
40
|
+
const scale = y > 1e-6 ? ySdr / y : 0;
|
|
41
|
+
out[base] = Math.round(linearToSrgb(Math.min(1, r * scale)) * 255);
|
|
42
|
+
out[base + 1] = Math.round(linearToSrgb(Math.min(1, g * scale)) * 255);
|
|
43
|
+
out[base + 2] = Math.round(linearToSrgb(Math.min(1, b * scale)) * 255);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/** Auto EV0 gain: geometric-mean luminance mapped to middle grey (~0.18). */
|
|
48
|
+
function middleGreyGain(data) {
|
|
49
|
+
let logSum = 0;
|
|
50
|
+
let count = 0;
|
|
51
|
+
for (let i = 0; i < data.length; i += 3) {
|
|
52
|
+
const y = luminance(data[i], data[i + 1], data[i + 2]);
|
|
53
|
+
if (y <= 0)
|
|
54
|
+
continue;
|
|
55
|
+
logSum += Math.log(y + 1e-4);
|
|
56
|
+
count++;
|
|
57
|
+
}
|
|
58
|
+
if (count === 0)
|
|
59
|
+
return 1;
|
|
60
|
+
return 0.18 / Math.max(1e-4, Math.exp(logSum / count));
|
|
61
|
+
}
|
|
62
|
+
/** Column-major 3x3 matrix multiply (three.js mat3 column vectors). */
|
|
63
|
+
function mul3(m, c) {
|
|
64
|
+
return [
|
|
65
|
+
m[0][0] * c[0] + m[1][0] * c[1] + m[2][0] * c[2],
|
|
66
|
+
m[0][1] * c[0] + m[1][1] * c[1] + m[2][1] * c[2],
|
|
67
|
+
m[0][2] * c[0] + m[1][2] * c[1] + m[2][2] * c[2],
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
const ACES_INPUT = [
|
|
71
|
+
[0.59719, 0.076, 0.0284],
|
|
72
|
+
[0.35458, 0.90834, 0.13383],
|
|
73
|
+
[0.04823, 0.01566, 0.83777],
|
|
74
|
+
];
|
|
75
|
+
const ACES_OUTPUT = [
|
|
76
|
+
[1.60475, -0.10208, -0.00327],
|
|
77
|
+
[-0.53108, 1.10813, -0.07276],
|
|
78
|
+
[-0.07367, -0.00605, 1.07602],
|
|
79
|
+
];
|
|
80
|
+
/** ACES RRT+ODT rational fit (one channel). */
|
|
81
|
+
function rrtOdt(x) {
|
|
82
|
+
const a = x * (x + 0.0245786) - 0.000090537;
|
|
83
|
+
const b = x * (0.983729 * x + 0.432951) + 0.238081;
|
|
84
|
+
return a / b;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* ACES Filmic tone map, ported from three.js (includes its subjective 1/0.6
|
|
88
|
+
* brightening). High contrast, cinematic highlight shoulder. Applied per pixel
|
|
89
|
+
* after an automatic middle-grey exposure.
|
|
90
|
+
*/
|
|
91
|
+
export function acesSdr(data, width, height) {
|
|
92
|
+
const exposure = middleGreyGain(data) / 0.6;
|
|
93
|
+
const out = Buffer.alloc(width * height * 3);
|
|
94
|
+
for (let pixel = 0; pixel < width * height; pixel++) {
|
|
95
|
+
const base = pixel * 3;
|
|
96
|
+
let c = [
|
|
97
|
+
Math.max(0, data[base]) * exposure,
|
|
98
|
+
Math.max(0, data[base + 1]) * exposure,
|
|
99
|
+
Math.max(0, data[base + 2]) * exposure,
|
|
100
|
+
];
|
|
101
|
+
c = mul3(ACES_INPUT, c);
|
|
102
|
+
c = [rrtOdt(c[0]), rrtOdt(c[1]), rrtOdt(c[2])];
|
|
103
|
+
c = mul3(ACES_OUTPUT, c);
|
|
104
|
+
out[base] = Math.round(linearToSrgb(c[0]) * 255);
|
|
105
|
+
out[base + 1] = Math.round(linearToSrgb(c[1]) * 255);
|
|
106
|
+
out[base + 2] = Math.round(linearToSrgb(c[2]) * 255);
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
const SRGB_TO_REC2020 = [
|
|
111
|
+
[0.6274, 0.0691, 0.0164],
|
|
112
|
+
[0.3293, 0.9195, 0.088],
|
|
113
|
+
[0.0433, 0.0113, 0.8956],
|
|
114
|
+
];
|
|
115
|
+
const REC2020_TO_SRGB = [
|
|
116
|
+
[1.6605, -0.1246, -0.0182],
|
|
117
|
+
[-0.5876, 1.1329, -0.1006],
|
|
118
|
+
[-0.0728, -0.0083, 1.1187],
|
|
119
|
+
];
|
|
120
|
+
const AGX_INSET = [
|
|
121
|
+
[0.856627153315983, 0.137318972929847, 0.11189821299995],
|
|
122
|
+
[0.0951212405381588, 0.761241990602591, 0.0767994186031903],
|
|
123
|
+
[0.0482516061458583, 0.101439036467562, 0.811302368396859],
|
|
124
|
+
];
|
|
125
|
+
const AGX_OUTSET = [
|
|
126
|
+
[1.1271005818144368, -0.1413297634984383, -0.14132976349843826],
|
|
127
|
+
[-0.11060664309660323, 1.157823702216272, -0.11060664309660294],
|
|
128
|
+
[-0.016493938717834573, -0.016493938717834257, 1.2519364065950405],
|
|
129
|
+
];
|
|
130
|
+
const AGX_MIN_EV = -12.47393;
|
|
131
|
+
const AGX_MAX_EV = 4.026069;
|
|
132
|
+
/** AgX sigmoid contrast polynomial (one channel), as in three.js. */
|
|
133
|
+
function agxContrast(x) {
|
|
134
|
+
const x2 = x * x;
|
|
135
|
+
const x4 = x2 * x2;
|
|
136
|
+
return (15.5 * x4 * x2 -
|
|
137
|
+
40.14 * x4 * x +
|
|
138
|
+
31.96 * x4 -
|
|
139
|
+
6.868 * x2 * x +
|
|
140
|
+
0.4298 * x2 +
|
|
141
|
+
0.1191 * x -
|
|
142
|
+
0.00232);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* AgX tone map (Filament/Blender fit), ported from three.js. Gentle, neutral
|
|
146
|
+
* highlight roll-off with low clipping. Applied per pixel after an automatic
|
|
147
|
+
* middle-grey exposure.
|
|
148
|
+
*/
|
|
149
|
+
export function agxSdr(data, width, height) {
|
|
150
|
+
const exposure = middleGreyGain(data);
|
|
151
|
+
const out = Buffer.alloc(width * height * 3);
|
|
152
|
+
for (let pixel = 0; pixel < width * height; pixel++) {
|
|
153
|
+
const base = pixel * 3;
|
|
154
|
+
let c = [
|
|
155
|
+
Math.max(0, data[base]) * exposure,
|
|
156
|
+
Math.max(0, data[base + 1]) * exposure,
|
|
157
|
+
Math.max(0, data[base + 2]) * exposure,
|
|
158
|
+
];
|
|
159
|
+
c = mul3(SRGB_TO_REC2020, c);
|
|
160
|
+
c = mul3(AGX_INSET, c);
|
|
161
|
+
c = [Math.max(c[0], 1e-10), Math.max(c[1], 1e-10), Math.max(c[2], 1e-10)];
|
|
162
|
+
c = [
|
|
163
|
+
(Math.log2(c[0]) - AGX_MIN_EV) / (AGX_MAX_EV - AGX_MIN_EV),
|
|
164
|
+
(Math.log2(c[1]) - AGX_MIN_EV) / (AGX_MAX_EV - AGX_MIN_EV),
|
|
165
|
+
(Math.log2(c[2]) - AGX_MIN_EV) / (AGX_MAX_EV - AGX_MIN_EV),
|
|
166
|
+
];
|
|
167
|
+
c = [clamp01(c[0]), clamp01(c[1]), clamp01(c[2])];
|
|
168
|
+
c = [agxContrast(c[0]), agxContrast(c[1]), agxContrast(c[2])];
|
|
169
|
+
c = mul3(AGX_OUTSET, c);
|
|
170
|
+
c = [Math.max(0, c[0]) ** 2.2, Math.max(0, c[1]) ** 2.2, Math.max(0, c[2]) ** 2.2];
|
|
171
|
+
c = mul3(REC2020_TO_SRGB, c);
|
|
172
|
+
// c is now linear sRGB; apply the sRGB OETF to get display 8-bit values.
|
|
173
|
+
out[base] = Math.round(linearToSrgb(c[0]) * 255);
|
|
174
|
+
out[base + 1] = Math.round(linearToSrgb(c[1]) * 255);
|
|
175
|
+
out[base + 2] = Math.round(linearToSrgb(c[2]) * 255);
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
/** Synthesise one virtual exposure as an sRGB-encoded RGB plane (0-1). */
|
|
180
|
+
function synthesiseExposure(hdr, n, gain) {
|
|
181
|
+
const out = new Float32Array(n * 3);
|
|
182
|
+
for (let i = 0; i < n * 3; i++)
|
|
183
|
+
out[i] = linearToSrgb(Math.max(0, hdr[i]) * gain);
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
/** Mertens per-pixel weight: contrast x saturation x well-exposedness. */
|
|
187
|
+
function exposureWeights(rgb, width, height) {
|
|
188
|
+
const n = width * height;
|
|
189
|
+
const y = new Float32Array(n);
|
|
190
|
+
for (let p = 0; p < n; p++)
|
|
191
|
+
y[p] = luminance(rgb[p * 3], rgb[p * 3 + 1], rgb[p * 3 + 2]);
|
|
192
|
+
// Contrast: |Laplacian| of the luminance.
|
|
193
|
+
const sample = (x, j) => y[Math.min(height - 1, Math.max(0, j)) * width + Math.min(width - 1, Math.max(0, x))];
|
|
194
|
+
const sigma = 0.2;
|
|
195
|
+
const out = new Float32Array(n);
|
|
196
|
+
for (let j = 0; j < height; j++) {
|
|
197
|
+
for (let i = 0; i < width; i++) {
|
|
198
|
+
const p = j * width + i;
|
|
199
|
+
const lap = Math.abs(sample(i, j - 1) +
|
|
200
|
+
sample(i, j + 1) +
|
|
201
|
+
sample(i - 1, j) +
|
|
202
|
+
sample(i + 1, j) -
|
|
203
|
+
4 * sample(i, j));
|
|
204
|
+
const r = rgb[p * 3];
|
|
205
|
+
const g = rgb[p * 3 + 1];
|
|
206
|
+
const b = rgb[p * 3 + 2];
|
|
207
|
+
const mean = (r + g + b) / 3;
|
|
208
|
+
const sat = Math.sqrt(((r - mean) ** 2 + (g - mean) ** 2 + (b - mean) ** 2) / 3);
|
|
209
|
+
const well = Math.exp(-((r - 0.5) ** 2) / (2 * sigma * sigma)) *
|
|
210
|
+
Math.exp(-((g - 0.5) ** 2) / (2 * sigma * sigma)) *
|
|
211
|
+
Math.exp(-((b - 0.5) ** 2) / (2 * sigma * sigma));
|
|
212
|
+
out[p] = lap * sat * well + 1e-12;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
const KERNEL = [0.0625, 0.25, 0.375, 0.25, 0.0625];
|
|
218
|
+
/** Separable 5-tap Gaussian downsample by 2 (ceil dimensions). */
|
|
219
|
+
function downsample(plane) {
|
|
220
|
+
const { width: w, height: h, data, channels } = plane;
|
|
221
|
+
const nw = Math.max(1, Math.ceil(w / 2));
|
|
222
|
+
const nh = Math.max(1, Math.ceil(h / 2));
|
|
223
|
+
const tmp = new Float32Array(nw * h * channels);
|
|
224
|
+
const clampX = (x) => Math.min(w - 1, Math.max(0, x));
|
|
225
|
+
for (let j = 0; j < h; j++) {
|
|
226
|
+
for (let i = 0; i < nw; i++) {
|
|
227
|
+
const cx = i * 2;
|
|
228
|
+
for (let c = 0; c < channels; c++) {
|
|
229
|
+
let s = 0;
|
|
230
|
+
for (let t = -2; t <= 2; t++)
|
|
231
|
+
s += KERNEL[t + 2] * data[(j * w + clampX(cx + t)) * channels + c];
|
|
232
|
+
tmp[(j * nw + i) * channels + c] = s;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const out = new Float32Array(nw * nh * channels);
|
|
237
|
+
const clampY = (yy) => Math.min(h - 1, Math.max(0, yy));
|
|
238
|
+
for (let j = 0; j < nh; j++) {
|
|
239
|
+
const cy = j * 2;
|
|
240
|
+
for (let i = 0; i < nw; i++) {
|
|
241
|
+
for (let c = 0; c < channels; c++) {
|
|
242
|
+
let s = 0;
|
|
243
|
+
for (let t = -2; t <= 2; t++)
|
|
244
|
+
s += KERNEL[t + 2] * tmp[(clampY(cy + t) * nw + i) * channels + c];
|
|
245
|
+
out[(j * nw + i) * channels + c] = s;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { width: nw, height: nh, data: out, channels };
|
|
250
|
+
}
|
|
251
|
+
/** Bilinear upsample to a target size (adequate for pyramid reconstruction). */
|
|
252
|
+
function upsample(plane, tw, th) {
|
|
253
|
+
const { width: w, height: h, data, channels } = plane;
|
|
254
|
+
const out = new Float32Array(tw * th * channels);
|
|
255
|
+
for (let j = 0; j < th; j++) {
|
|
256
|
+
const sy = (j * h) / th;
|
|
257
|
+
const y0 = Math.min(h - 1, Math.floor(sy));
|
|
258
|
+
const y1 = Math.min(h - 1, y0 + 1);
|
|
259
|
+
const fy = sy - y0;
|
|
260
|
+
for (let i = 0; i < tw; i++) {
|
|
261
|
+
const sx = (i * w) / tw;
|
|
262
|
+
const x0 = Math.min(w - 1, Math.floor(sx));
|
|
263
|
+
const x1 = Math.min(w - 1, x0 + 1);
|
|
264
|
+
const fx = sx - x0;
|
|
265
|
+
for (let c = 0; c < channels; c++) {
|
|
266
|
+
const a = data[(y0 * w + x0) * channels + c];
|
|
267
|
+
const b = data[(y0 * w + x1) * channels + c];
|
|
268
|
+
const cc = data[(y1 * w + x0) * channels + c];
|
|
269
|
+
const dd = data[(y1 * w + x1) * channels + c];
|
|
270
|
+
out[(j * tw + i) * channels + c] =
|
|
271
|
+
a * (1 - fx) * (1 - fy) + b * fx * (1 - fy) + cc * (1 - fx) * fy + dd * fx * fy;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return { width: tw, height: th, data: out, channels };
|
|
276
|
+
}
|
|
277
|
+
function gaussianPyramid(plane, levels) {
|
|
278
|
+
const pyramid = [plane];
|
|
279
|
+
for (let l = 1; l < levels; l++)
|
|
280
|
+
pyramid.push(downsample(pyramid[l - 1]));
|
|
281
|
+
return pyramid;
|
|
282
|
+
}
|
|
283
|
+
function laplacianPyramid(plane, levels) {
|
|
284
|
+
const gauss = gaussianPyramid(plane, levels);
|
|
285
|
+
const laplacian = [];
|
|
286
|
+
for (let l = 0; l < levels - 1; l++) {
|
|
287
|
+
const up = upsample(gauss[l + 1], gauss[l].width, gauss[l].height);
|
|
288
|
+
const diff = new Float32Array(gauss[l].data.length);
|
|
289
|
+
for (let i = 0; i < diff.length; i++)
|
|
290
|
+
diff[i] = gauss[l].data[i] - up.data[i];
|
|
291
|
+
laplacian.push({
|
|
292
|
+
width: gauss[l].width,
|
|
293
|
+
height: gauss[l].height,
|
|
294
|
+
data: diff,
|
|
295
|
+
channels: plane.channels,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
laplacian.push(gauss[levels - 1]);
|
|
299
|
+
return laplacian;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Exposure fusion tone map. Synthesises `exposureCount` exposures around an
|
|
303
|
+
* auto middle-grey EV0, blends them with Mertens weights over a Laplacian
|
|
304
|
+
* pyramid, and returns interleaved 8-bit sRGB RGB.
|
|
305
|
+
*/
|
|
306
|
+
export function exposureFusion(data, width, height, options = {}) {
|
|
307
|
+
const evStep = options.evStep ?? 2;
|
|
308
|
+
const count = Math.max(1, options.exposureCount ?? 5);
|
|
309
|
+
const n = width * height;
|
|
310
|
+
const ev0Gain = middleGreyGain(data);
|
|
311
|
+
const levels = Math.max(2, Math.floor(Math.log2(Math.min(width, height))) - 1);
|
|
312
|
+
const half = (count - 1) / 2;
|
|
313
|
+
// Synthesise exposures and their (unnormalised) weights.
|
|
314
|
+
const images = [];
|
|
315
|
+
const weights = [];
|
|
316
|
+
const weightSum = new Float32Array(n);
|
|
317
|
+
for (let k = 0; k < count; k++) {
|
|
318
|
+
const gain = ev0Gain * 2 ** ((k - half) * evStep);
|
|
319
|
+
const image = synthesiseExposure(data, n, gain);
|
|
320
|
+
const weight = exposureWeights(image, width, height);
|
|
321
|
+
images.push(image);
|
|
322
|
+
weights.push(weight);
|
|
323
|
+
for (let p = 0; p < n; p++)
|
|
324
|
+
weightSum[p] += weight[p];
|
|
325
|
+
}
|
|
326
|
+
for (const weight of weights)
|
|
327
|
+
for (let p = 0; p < n; p++)
|
|
328
|
+
weight[p] /= weightSum[p];
|
|
329
|
+
// Blend in the Laplacian domain: fused L = sum_k L(image_k) * G(weight_k).
|
|
330
|
+
let fused;
|
|
331
|
+
for (let k = 0; k < count; k++) {
|
|
332
|
+
const imageLaplacian = laplacianPyramid({ width, height, data: images[k], channels: 3 }, levels);
|
|
333
|
+
const weightGaussian = gaussianPyramid({ width, height, data: weights[k], channels: 1 }, levels);
|
|
334
|
+
if (!fused) {
|
|
335
|
+
fused = imageLaplacian.map((p) => ({
|
|
336
|
+
width: p.width,
|
|
337
|
+
height: p.height,
|
|
338
|
+
data: new Float32Array(p.data.length),
|
|
339
|
+
channels: 3,
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
for (let l = 0; l < levels; l++) {
|
|
343
|
+
const laplacian = imageLaplacian[l].data;
|
|
344
|
+
const weight = weightGaussian[l].data;
|
|
345
|
+
const destination = fused[l].data;
|
|
346
|
+
const pixels = fused[l].width * fused[l].height;
|
|
347
|
+
for (let p = 0; p < pixels; p++) {
|
|
348
|
+
const w = weight[p];
|
|
349
|
+
destination[p * 3] += laplacian[p * 3] * w;
|
|
350
|
+
destination[p * 3 + 1] += laplacian[p * 3 + 1] * w;
|
|
351
|
+
destination[p * 3 + 2] += laplacian[p * 3 + 2] * w;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Collapse the fused Laplacian pyramid back to full resolution.
|
|
356
|
+
let accumulator = fused[levels - 1];
|
|
357
|
+
for (let l = levels - 2; l >= 0; l--) {
|
|
358
|
+
const up = upsample(accumulator, fused[l].width, fused[l].height);
|
|
359
|
+
const sum = new Float32Array(up.data.length);
|
|
360
|
+
for (let i = 0; i < sum.length; i++)
|
|
361
|
+
sum[i] = up.data[i] + fused[l].data[i];
|
|
362
|
+
accumulator = { width: fused[l].width, height: fused[l].height, data: sum, channels: 3 };
|
|
363
|
+
}
|
|
364
|
+
const out = Buffer.alloc(n * 3);
|
|
365
|
+
for (let i = 0; i < n * 3; i++)
|
|
366
|
+
out[i] = Math.round(clamp01(accumulator.data[i]) * 255);
|
|
367
|
+
return out;
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=tonemap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonemap.js","sourceRoot":"","sources":["../src/tonemap.ts"],"names":[],"mappings":"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"}
|