rayzee 8.5.0 → 8.6.0

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.
Files changed (60) hide show
  1. package/README.md +60 -4
  2. package/dist/{DLSSNeural-BNSJ8V3z.js → DLSSNeural-BhBCBgKf.js} +5 -5
  3. package/dist/{DLSSSuperRes-BoEW89Cl.js → DLSSSuperRes-BCA7F_k5.js} +5 -5
  4. package/dist/ToneMapGPU-BzcLheoR.js +533 -0
  5. package/dist/rayzee.es.js +27198 -9047
  6. package/dist/rayzee.umd.js +255 -187
  7. package/package.json +1 -1
  8. package/src/AssetConfig.js +15 -2
  9. package/src/Color/BakedViews.js +134 -0
  10. package/src/Color/BuiltinViews.js +261 -0
  11. package/src/Color/ColorManagement.js +1130 -0
  12. package/src/Color/ColorSpaces.js +432 -0
  13. package/src/Color/Displays.js +19 -0
  14. package/src/Color/InputColorSpaces.js +243 -0
  15. package/src/Color/LutBake.js +371 -0
  16. package/src/Color/OcioRuntime.js +338 -0
  17. package/src/Color/OcioViews.js +419 -0
  18. package/src/Color/ViewTransforms.js +323 -0
  19. package/src/Color/WorkingMatrix.js +86 -0
  20. package/src/EngineDefaults.js +55 -3
  21. package/src/EngineIssues.js +3 -0
  22. package/src/Passes/AIUpscaler.js +16 -7
  23. package/src/PathTracerApp.js +227 -7
  24. package/src/Processor/AssetLoader.js +1 -2
  25. package/src/Processor/EmissiveTriangleBuilder.js +34 -2
  26. package/src/Processor/GeometryExtractor.js +151 -138
  27. package/src/Processor/LightSerializer.js +8 -3
  28. package/src/Processor/MaterialPacking.js +168 -0
  29. package/src/Processor/PackedRayBuffer.js +6 -2
  30. package/src/Processor/ProceduralSky.js +4 -0
  31. package/src/Processor/SceneProcessor.js +25 -1
  32. package/src/Processor/SimpleSky.js +8 -0
  33. package/src/Processor/TextureCreator.js +137 -91
  34. package/src/Processor/TextureReadback.js +92 -0
  35. package/src/Processor/ToneMapCPU.js +80 -165
  36. package/src/Processor/ToneMapGPU.js +122 -151
  37. package/src/RenderSettings.js +1 -0
  38. package/src/Stages/Compositor.js +11 -2
  39. package/src/Stages/PathTracer.js +2 -0
  40. package/src/Stages/PathTracerStage.js +1 -1
  41. package/src/TSL/Common.js +15 -0
  42. package/src/TSL/Debugger.js +2 -3
  43. package/src/TSL/EmissiveSampling.js +6 -8
  44. package/src/TSL/ExtendKernel.js +9 -0
  45. package/src/TSL/Fresnel.js +23 -1
  46. package/src/TSL/HitFacet.js +102 -0
  47. package/src/TSL/LightsDirect.js +12 -33
  48. package/src/TSL/LightsSampling.js +15 -7
  49. package/src/TSL/MaterialEvaluation.js +26 -19
  50. package/src/TSL/MaterialProperties.js +74 -37
  51. package/src/TSL/MaterialTransmission.js +2 -3
  52. package/src/TSL/ShadeKernel.js +34 -21
  53. package/src/TSL/ShadowTerminator.js +125 -0
  54. package/src/TSL/Struct.js +9 -0
  55. package/src/TSL/Subsurface.js +2 -3
  56. package/src/index.js +29 -1
  57. package/src/managers/EnvironmentManager.js +20 -0
  58. package/src/managers/MaterialDataManager.js +118 -208
  59. package/src/managers/UniformManager.js +1 -0
  60. package/dist/ToneMapGPU-DzqSyzTx.js +0 -341
@@ -0,0 +1,533 @@
1
+ import { ACESFilmicToneMapping as e, AgXToneMapping as t, CineonToneMapping as n, LinearToneMapping as r, NeutralToneMapping as i, NoToneMapping as a, ReinhardToneMapping as o } from "three";
2
+ //#region src/utils/Logger.js
3
+ var s = {
4
+ silent: 0,
5
+ error: 1,
6
+ warn: 2,
7
+ info: 3,
8
+ debug: 4
9
+ }, c = "info", l = "rayzeeLogLevel", u = "rayzeeLogNamespaces", d = "color:#7c8494", f = "color:inherit", p = null, m = null;
10
+ function h(e) {
11
+ try {
12
+ return globalThis.localStorage?.getItem(e) ?? null;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+ function g(e, t) {
18
+ try {
19
+ t === null ? globalThis.localStorage?.removeItem(e) : globalThis.localStorage?.setItem(e, t);
20
+ } catch {}
21
+ }
22
+ function _() {
23
+ if (p !== null) return p;
24
+ let e = globalThis.__RAYZEE_LOG_LEVEL__;
25
+ return e !== void 0 && e in s ? (p = s[e], p) : (p = s[h(l)] ?? s[c], p);
26
+ }
27
+ function v() {
28
+ if (m !== null) return m;
29
+ let e = globalThis.__RAYZEE_LOG_NS__ ?? h(u);
30
+ return m = e ? String(e).split(",").map((e) => e.trim()).filter(Boolean) : [], m;
31
+ }
32
+ function y(e, t) {
33
+ if (t < s.debug) return !0;
34
+ let n = v();
35
+ return n.length === 0 || n.some((t) => e === t || e.startsWith(`${t}:`));
36
+ }
37
+ function b(e, t, n) {
38
+ if (e > _() || !y(t, e)) return;
39
+ let r = e === s.error ? console.error : e === s.warn ? console.warn : console.log, i = `[${t}]`;
40
+ typeof n[0] == "string" ? r(`%c${i}%c ${n[0]}`, d, f, ...n.slice(1)) : r(`%c${i}`, d, ...n);
41
+ }
42
+ var x = {
43
+ n: (e) => Number(e).toLocaleString("en-US"),
44
+ ms: (e) => e < 10 ? `${Number(e).toFixed(1)} ms` : `${Math.round(e)} ms`,
45
+ mb: (e) => {
46
+ let t = e / (1024 * 1024);
47
+ return t < 10 ? `${t.toFixed(1)} MB` : `${Math.round(t)} MB`;
48
+ },
49
+ px: (e, t) => `${e}×${t}`,
50
+ count: (e, t, n = `${t}s`) => `${x.n(e)} ${Number(e) === 1 ? t : n}`,
51
+ list: (e) => e.filter(Boolean).join(" · ")
52
+ }, S = {
53
+ levels: s,
54
+ setLevel(e) {
55
+ return e in s ? (globalThis.__RAYZEE_LOG_LEVEL__ = e, p = s[e], g(l, e === c ? null : e), e) : (console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(s).join(", ")}`), this.getLevel());
56
+ },
57
+ getLevel() {
58
+ let e = _();
59
+ return Object.keys(s).find((t) => s[t] === e);
60
+ },
61
+ isEnabled(e) {
62
+ return (s[e] ?? s.debug) <= _();
63
+ },
64
+ only(...e) {
65
+ let t = e.flat().filter(Boolean);
66
+ return m = t, globalThis.__RAYZEE_LOG_NS__ = t.join(","), g(u, t.length ? t.join(",") : null), t.length && this.setLevel("debug"), t;
67
+ },
68
+ refresh() {
69
+ return p = null, m = null, this.getLevel();
70
+ }
71
+ };
72
+ function C(e) {
73
+ return {
74
+ namespace: e,
75
+ error: (...t) => b(s.error, e, t),
76
+ warn: (...t) => b(s.warn, e, t),
77
+ info: (...t) => b(s.info, e, t),
78
+ debug: (...t) => b(s.debug, e, t),
79
+ isEnabled: (e) => S.isEnabled(e),
80
+ summary(t, n = []) {
81
+ let r = n.filter(Boolean);
82
+ if (r.length === 0 || !console.groupCollapsed) {
83
+ b(s.info, e, [t]), r.forEach((t) => b(s.debug, e, [t]));
84
+ return;
85
+ }
86
+ s.info > _() || ((_() >= s.debug && console.group ? console.group : console.groupCollapsed)(`%c[${e}]%c ${t}`, d, f), r.forEach((e) => console.log(e)), console.groupEnd());
87
+ }
88
+ };
89
+ }
90
+ var w = /* @__PURE__ */ new Set();
91
+ function T(e, t, ...n) {
92
+ w.has(t) || (w.add(t), e.warn(...n));
93
+ }
94
+ function E() {
95
+ return S.getLevel();
96
+ }
97
+ //#endregion
98
+ //#region src/AssetConfig.js
99
+ var D = {
100
+ stbnScalarAtlas: "https://assets.rayzee.atulmourya.com/noise/stbn_scalar_atlas.png",
101
+ stbnVec2Atlas: "https://assets.rayzee.atulmourya.com/noise/stbn_vec2_atlas.png",
102
+ ortRuntimeUrl: "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs",
103
+ ortWasmPaths: "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/",
104
+ dracoDecoderPath: "https://www.gstatic.com/draco/v1/decoders/",
105
+ ktx2TranscoderPath: "https://cdn.jsdelivr.net/npm/three@0.183.2/examples/jsm/libs/basis/",
106
+ oidnWeightsBaseUrl: "https://assets.rayzee.atulmourya.com/oidn/denoiser-0.0.11/",
107
+ ocioRuntimeFactory: null,
108
+ ocioRuntimeUrl: null,
109
+ ocioWasmUrl: null,
110
+ upscalerModelBaseUrl: "https://huggingface.co/notaneimu/onnx-image-models/resolve/main/",
111
+ dlssRuntimeUrl: "/dlss/dlss-runtime.js",
112
+ dlssAssetBaseUrl: "https://pub-6e048ff014374f11bef33d76b6c2b5ef.r2.dev/v1",
113
+ cacheNamespace: "rayzee"
114
+ };
115
+ function O(e) {
116
+ e && Object.assign(D, e);
117
+ }
118
+ function k() {
119
+ return { ...D };
120
+ }
121
+ //#endregion
122
+ //#region src/Color/BuiltinViews.js
123
+ var A = (e) => Math.min(Math.max(e, 0), 1);
124
+ function j(e, t, n, r, i) {
125
+ i[0] = A(e), i[1] = A(t), i[2] = A(n);
126
+ }
127
+ function ee(e, t, n, r, i) {
128
+ i[0] = A(e * r), i[1] = A(t * r), i[2] = A(n * r);
129
+ }
130
+ function te(e, t, n, r, i) {
131
+ e *= r, t *= r, n *= r, i[0] = A(e / (e + 1)), i[1] = A(t / (t + 1)), i[2] = A(n / (n + 1));
132
+ }
133
+ function ne(e, t, n, r, i) {
134
+ e = Math.max(e * r - .004, 0), t = Math.max(t * r - .004, 0), n = Math.max(n * r - .004, 0);
135
+ let a = (e) => (e * (6.2 * e + .5) / (e * (6.2 * e + 1.7) + .06)) ** 2.2;
136
+ i[0] = a(e), i[1] = a(t), i[2] = a(n);
137
+ }
138
+ function re(e, t, n, r, i) {
139
+ e = e * r / .6, t = t * r / .6, n = n * r / .6;
140
+ let a = .59719 * e + .35458 * t + .04823 * n, o = .076 * e + .90834 * t + .01566 * n, s = .0284 * e + .13383 * t + .83777 * n, c = (e) => (e * (e + .0245786) - 90537e-9) / (e * (.983729 * e + .432951) + .238081);
141
+ a = c(a), o = c(o), s = c(s), i[0] = A(1.60475 * a - .53108 * o - .07367 * s), i[1] = A(-.10208 * a + 1.10813 * o - .00605 * s), i[2] = A(-.00327 * a - .07276 * o + 1.07602 * s);
142
+ }
143
+ function M(e, t, n, r, i) {
144
+ e *= r, t *= r, n *= r;
145
+ let a = .6274 * e + .3293 * t + .0433 * n, o = .0691 * e + .9195 * t + .0113 * n, s = .0164 * e + .088 * t + .8956 * n, c = .856627153315983 * a + .0951212405381588 * o + .0482516061458583 * s, l = .137318972929847 * a + .761241990602591 * o + .101439036467562 * s, u = .11189821299995 * a + .0767994186031903 * o + .811302368396859 * s, d = -12.47393, f = 4.026069 - d;
146
+ c = A((Math.log2(Math.max(c, 1e-10)) - d) / f), l = A((Math.log2(Math.max(l, 1e-10)) - d) / f), u = A((Math.log2(Math.max(u, 1e-10)) - d) / f);
147
+ let p = (e) => {
148
+ let t = e * e, n = t * t;
149
+ return 15.5 * n * t - 40.14 * n * e + 31.96 * n - 6.868 * t * e + .4298 * t + .1191 * e - .00232;
150
+ };
151
+ c = p(c), l = p(l), u = p(u);
152
+ let m = 1.1271005818144368 * c - .11060664309660323 * l - .016493938717834573 * u, h = -.1413297634984383 * c + 1.157823702216272 * l - .016493938717834257 * u, g = -.14132976349843826 * c - .11060664309660294 * l + 1.2519364065950405 * u;
153
+ m = Math.max(0, m) ** 2.2, h = Math.max(0, h) ** 2.2, g = Math.max(0, g) ** 2.2, i[0] = A(1.6605 * m - .5876 * h - .0728 * g), i[1] = A(-.1246 * m + 1.1329 * h - .0083 * g), i[2] = A(-.0182 * m - .1006 * h + 1.1187 * g);
154
+ }
155
+ function N(e, t, n, r, i) {
156
+ let a = .76;
157
+ e *= r, t *= r, n *= r;
158
+ let o = Math.min(e, Math.min(t, n)), s = o < .08 ? o - 6.25 * o * o : .04;
159
+ e -= s, t -= s, n -= s;
160
+ let c = Math.max(e, Math.max(t, n));
161
+ if (c < a) {
162
+ i[0] = e, i[1] = t, i[2] = n;
163
+ return;
164
+ }
165
+ let l = 1 - a, u = 1 - l * l / (c + l - a), d = u / c;
166
+ e *= d, t *= d, n *= d;
167
+ let f = 1 - 1 / (.15 * (c - u) + 1);
168
+ i[0] = e + (u - e) * f, i[1] = t + (u - t) * f, i[2] = n + (u - n) * f;
169
+ }
170
+ var P = [
171
+ {
172
+ id: a,
173
+ name: "None",
174
+ wgslConst: "TM_NONE",
175
+ cpu: j,
176
+ wgsl: null,
177
+ call: null,
178
+ appliesExposure: !1
179
+ },
180
+ {
181
+ id: r,
182
+ name: "Linear",
183
+ wgslConst: "TM_LINEAR",
184
+ cpu: ee,
185
+ wgsl: null,
186
+ call: null
187
+ },
188
+ {
189
+ id: o,
190
+ name: "Reinhard",
191
+ wgslConst: "TM_REINHARD",
192
+ cpu: te,
193
+ wgsl: "\nfn tm_reinhard( c: vec3<f32> ) -> vec3<f32> {\n return clamp( c / ( c + vec3<f32>( 1.0 ) ), vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );\n}\n",
194
+ call: "tm_reinhard( c )"
195
+ },
196
+ {
197
+ id: n,
198
+ name: "Cineon",
199
+ wgslConst: "TM_CINEON",
200
+ cpu: ne,
201
+ wgsl: "\nfn tm_cineon( c0: vec3<f32> ) -> vec3<f32> {\n let c = max( c0 - vec3<f32>( 0.004 ), vec3<f32>( 0.0 ) );\n let v = ( c * ( 6.2 * c + vec3<f32>( 0.5 ) ) ) / ( c * ( 6.2 * c + vec3<f32>( 1.7 ) ) + vec3<f32>( 0.06 ) );\n return pow( max( v, vec3<f32>( 0.0 ) ), vec3<f32>( 2.2 ) );\n}\n",
202
+ call: "tm_cineon( c )"
203
+ },
204
+ {
205
+ id: e,
206
+ name: "ACES Filmic",
207
+ wgslConst: "TM_ACES",
208
+ cpu: re,
209
+ wgsl: "\nfn tm_aces( c0: vec3<f32> ) -> vec3<f32> {\n let c = c0 / 0.6;\n let m_in = mat3x3<f32>(\n vec3<f32>( 0.59719, 0.07600, 0.02840 ),\n vec3<f32>( 0.35458, 0.90834, 0.13383 ),\n vec3<f32>( 0.04823, 0.01566, 0.83777 ) );\n let v = m_in * c;\n let a = v * ( v + vec3<f32>( 0.0245786 ) ) - vec3<f32>( 0.000090537 );\n let b = v * ( 0.983729 * v + vec3<f32>( 0.4329510 ) ) + vec3<f32>( 0.238081 );\n let m_out = mat3x3<f32>(\n vec3<f32>( 1.60475, -0.10208, -0.00327 ),\n vec3<f32>( -0.53108, 1.10813, -0.07276 ),\n vec3<f32>( -0.07367, -0.00605, 1.07602 ) );\n return clamp( m_out * ( a / b ), vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );\n}\n",
210
+ call: "tm_aces( c )"
211
+ },
212
+ {
213
+ id: t,
214
+ name: "AgX",
215
+ wgslConst: "TM_AGX",
216
+ cpu: M,
217
+ wgsl: "\nfn tm_agx( c0: vec3<f32> ) -> vec3<f32> {\n let m_in = mat3x3<f32>(\n vec3<f32>( 0.6274, 0.0691, 0.0164 ),\n vec3<f32>( 0.3293, 0.9195, 0.0880 ),\n vec3<f32>( 0.0433, 0.0113, 0.8956 ) );\n let m_agx = mat3x3<f32>(\n vec3<f32>( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n vec3<f32>( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n vec3<f32>( 0.0482516061458583, 0.101439036467562, 0.811302368396859 ) );\n\n var v = m_agx * ( m_in * c0 );\n\n let minEv = -12.47393;\n let maxEv = 4.026069;\n v = clamp( ( log2( max( v, vec3<f32>( 1e-10 ) ) ) - vec3<f32>( minEv ) ) / ( maxEv - minEv ),\n vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );\n\n let x2 = v * v;\n let x4 = x2 * x2;\n v = 15.5 * x4 * x2 - 40.14 * x4 * v + 31.96 * x4 - 6.868 * x2 * v + 0.4298 * x2 + 0.1191 * v\n - vec3<f32>( 0.00232 );\n\n let m_out = mat3x3<f32>(\n vec3<f32>( 1.1271005818144368, -0.1413297634984383, -0.14132976349843826 ),\n vec3<f32>( -0.11060664309660323, 1.157823702216272, -0.11060664309660294 ),\n vec3<f32>( -0.016493938717834573, -0.016493938717834257, 1.2519364065950405 ) );\n let o = pow( max( m_out * v, vec3<f32>( 0.0 ) ), vec3<f32>( 2.2 ) );\n\n let m_srgb = mat3x3<f32>(\n vec3<f32>( 1.6605, -0.1246, -0.0182 ),\n vec3<f32>( -0.5876, 1.1329, -0.1006 ),\n vec3<f32>( -0.0728, -0.0083, 1.1187 ) );\n return clamp( m_srgb * o, vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );\n}\n",
218
+ call: "tm_agx( c )"
219
+ },
220
+ {
221
+ id: i,
222
+ name: "Neutral",
223
+ wgslConst: "TM_NEUTRAL",
224
+ cpu: N,
225
+ wgsl: "\nfn tm_neutral( c0: vec3<f32> ) -> vec3<f32> {\n let startCompression = 0.8 - 0.04;\n let desaturation = 0.15;\n\n let x = min( c0.r, min( c0.g, c0.b ) );\n var offset = 0.04;\n if ( x < 0.08 ) { offset = x - 6.25 * x * x; }\n var c = c0 - vec3<f32>( offset );\n\n let peak = max( c.r, max( c.g, c.b ) );\n if ( peak < startCompression ) { return c; }\n\n let d = 1.0 - startCompression;\n let newPeak = 1.0 - d * d / ( peak + d - startCompression );\n c = c * ( newPeak / peak );\n let gFactor = 1.0 - 1.0 / ( desaturation * ( peak - newPeak ) + 1.0 );\n return mix( c, vec3<f32>( newPeak ), gFactor );\n}\n",
226
+ call: "tm_neutral( c )"
227
+ }
228
+ ].map((e) => ({
229
+ source: "builtin",
230
+ outputEncoded: !1,
231
+ appliesExposure: !0,
232
+ ...e
233
+ })), F = 200, I = 12, L = [...P], R = new Map(L.map((e) => [e.id, e])), z = 1, B = /* @__PURE__ */ new Set();
234
+ function V() {
235
+ z++;
236
+ for (let e of B) e();
237
+ }
238
+ var H = R;
239
+ function U() {
240
+ return z;
241
+ }
242
+ function W(e) {
243
+ return B.add(e), () => B.delete(e);
244
+ }
245
+ function G(e) {
246
+ return R.get(e) ?? null;
247
+ }
248
+ function K() {
249
+ return L.map((e) => ({
250
+ id: e.id,
251
+ name: e.name,
252
+ source: e.source,
253
+ display: e.ocio?.display ?? null,
254
+ view: e.ocio?.view ?? null,
255
+ look: e.ocio?.look ?? null
256
+ }));
257
+ }
258
+ function q() {
259
+ return L.filter((e) => e.table).length;
260
+ }
261
+ function J() {
262
+ let e = 200;
263
+ for (; R.has(e);) e++;
264
+ return e;
265
+ }
266
+ function Y(e) {
267
+ if (typeof e?.id != "number") throw Error("view transform needs a numeric id");
268
+ if (typeof e.cpu != "function") throw Error(`view transform ${e.id} needs a cpu function`);
269
+ if (!e.name) throw Error(`view transform ${e.id} needs a name`);
270
+ if (!/^TM_[A-Z0-9_]+$/.test(e.wgslConst ?? "")) throw Error(`view transform ${e.id} needs a wgslConst like TM_SOMETHING`);
271
+ let t = R.get(e.id);
272
+ if (!t && e.table && q() >= 12) throw Error(`cannot register "${e.name}": 12 table-backed view transforms already registered, and WebGPU only guarantees 16 sampled textures per stage. Remove one first.`);
273
+ let n = {
274
+ source: "custom",
275
+ outputEncoded: !1,
276
+ appliesExposure: !0,
277
+ ...e
278
+ };
279
+ return t ? L[L.indexOf(t)] = n : L.push(n), R.set(n.id, n), V(), n;
280
+ }
281
+ function ie(e) {
282
+ let t = R.get(e);
283
+ return t ? (L.splice(L.indexOf(t), 1), R.delete(e), V(), !0) : !1;
284
+ }
285
+ function ae(e = null) {
286
+ let t = L.filter((t) => t.source === "ocio" && !e?.has(t.id)).map((e) => e.id);
287
+ if (t.length === 0) return 0;
288
+ for (let e of t) {
289
+ let t = R.get(e);
290
+ L.splice(L.indexOf(t), 1), R.delete(e);
291
+ }
292
+ return V(), t.length;
293
+ }
294
+ function oe(e) {
295
+ let t = e?.library;
296
+ if (!t?.addToneMapping) return 0;
297
+ let n = 0;
298
+ for (let e of L) e.tsl && (t.toneMappingNodes?.delete(e.id), t.addToneMapping(e.tsl, e.id), n++);
299
+ return n;
300
+ }
301
+ function X({ group: e = 0, firstBinding: t = 3 } = {}) {
302
+ let n = [], r = t, i = [], a = [];
303
+ for (let t of L) {
304
+ if (t.table) {
305
+ let a = `${t.wgslConst.toLowerCase()}_tex`;
306
+ i.push(`@group(${e}) @binding(${r}) var ${a}: texture_3d<f32>;`), n.push({
307
+ index: r,
308
+ transform: t,
309
+ texName: a
310
+ }), r += 1;
311
+ }
312
+ t.wgsl && a.push(t.wgsl);
313
+ }
314
+ let o = L.map((e) => `const ${e.wgslConst}: u32 = ${e.id}u;`).join("\n"), s = L.filter((e) => e.call).map((e) => `\tif ( mode == ${e.wgslConst} ) { return ${e.call}; }`).join("\n"), c = L.filter((e) => e.outputEncoded).map((e) => e.wgslConst), l = c.length ? c.map((e) => `mode == ${e}`).join(" || ") : "false", u = L.filter((e) => !e.appliesExposure).map((e) => e.wgslConst), d = u.length ? u.map((e) => `mode == ${e}`).join(" || ") : "false";
315
+ return {
316
+ wgsl: `
317
+ ${o}
318
+
319
+ ${i.join("\n")}
320
+
321
+ ${a.join("\n")}
322
+
323
+ // Three.js clamps the fragment output with max(0) before tone mapping, so the curves never see a
324
+ // negative channel. The saturation grade drives channels below zero on much of a typical frame,
325
+ // and AgX/Neutral mix negatives across channels instead of clipping them.
326
+ fn rayzee_tone_curve( color: vec3<f32>, mode: u32 ) -> vec3<f32> {
327
+ let c = max( color, vec3<f32>( 0.0 ) );
328
+ ${s}
329
+ return clamp( c, vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );
330
+ }
331
+
332
+ /** True when the curve already returned display-encoded colour. */
333
+ fn rayzee_output_encoded( mode: u32 ) -> bool {
334
+ return ${l};
335
+ }
336
+
337
+ fn rayzee_tone_map( linearRGB: vec3<f32>, mode: u32, exposure: f32, saturation: f32 ) -> vec3<f32> {
338
+ // Three.js returns early for NoToneMapping without applying exposure, so a readback that
339
+ // applied it would paint brighter than the viewport it replaces.
340
+ var c = linearRGB * select( exposure, 1.0, ${d} );
341
+ if ( saturation != 1.0 ) {
342
+ let luma = vec3<f32>( dot( c, vec3<f32>( 0.2126, 0.7152, 0.0722 ) ) );
343
+ c = luma + ( c - luma ) * saturation;
344
+ }
345
+ return rayzee_tone_curve( c, mode );
346
+ }
347
+
348
+ fn rayzee_linear_to_srgb( c: vec3<f32> ) -> vec3<f32> {
349
+ return select(
350
+ 1.055 * pow( max( c, vec3<f32>( 0.0 ) ), vec3<f32>( 1.0 / 2.4 ) ) - vec3<f32>( 0.055 ),
351
+ 12.92 * c,
352
+ c <= vec3<f32>( 0.0031308 ) );
353
+ }
354
+
355
+ /** The transfer step, skipped for a curve that already encoded its own output. */
356
+ fn rayzee_encode( mapped: vec3<f32>, mode: u32 ) -> vec3<f32> {
357
+ if ( rayzee_output_encoded( mode ) ) { return clamp( mapped, vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) ); }
358
+ return rayzee_linear_to_srgb( mapped );
359
+ }
360
+
361
+ fn rayzee_to_u8( srgb: vec3<f32> ) -> vec3<u32> {
362
+ return vec3<u32>( clamp( round( srgb * 255.0 + vec3<f32>( 0.5 ) ), vec3<f32>( 0.0 ), vec3<f32>( 255.0 ) ) );
363
+ }
364
+ `,
365
+ bindings: n
366
+ };
367
+ }
368
+ function se() {
369
+ L.length = 0, L.push(...P), R.clear();
370
+ for (let e of L) R.set(e.id, e);
371
+ V();
372
+ }
373
+ var ce = a, Z = 0, le = 3;
374
+ function Q() {
375
+ let { wgsl: e, bindings: t } = X({
376
+ group: Z,
377
+ firstBinding: le
378
+ });
379
+ return {
380
+ wgsl: e,
381
+ bindings: t,
382
+ version: U()
383
+ };
384
+ }
385
+ Q().wgsl;
386
+ var ue = (e) => `
387
+ struct Params {
388
+ width: u32,
389
+ height: u32,
390
+ mode: u32,
391
+ flipY: u32,
392
+ exposure: f32,
393
+ saturation: f32,
394
+ };
395
+
396
+ @group(0) @binding(0) var<storage, read> src: array<u32>;
397
+ @group(0) @binding(1) var<storage, read_write> dst: array<u32>;
398
+ @group(0) @binding(2) var<uniform> params: Params;
399
+
400
+ ${e}
401
+
402
+ @compute @workgroup_size(8, 8)
403
+ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
404
+ if ( gid.x >= params.width || gid.y >= params.height ) { return; }
405
+
406
+ var srcY = gid.y;
407
+ if ( params.flipY == 1u ) { srcY = params.height - 1u - gid.y; }
408
+
409
+ let a = ( srcY * params.width + gid.x ) * 2u;
410
+ let rg = unpack2x16float( src[ a ] );
411
+ let ba = unpack2x16float( src[ a + 1u ] );
412
+
413
+ let mapped = rayzee_tone_map( vec3<f32>( rg.x, rg.y, ba.x ), params.mode, params.exposure, params.saturation );
414
+ let b8 = rayzee_to_u8( rayzee_encode( mapped, params.mode ) );
415
+ dst[ gid.y * params.width + gid.x ] = b8.x | ( b8.y << 8u ) | ( b8.z << 16u ) | ( 255u << 24u );
416
+ }
417
+ `, $ = 32, de = class {
418
+ constructor(e, t = "rayzee:tonemap") {
419
+ this.device = e, this.label = t, this.width = 0, this.height = 0, this._pipeline = null, this._storage = null, this._map = null, this._params = null, this._paramData = new ArrayBuffer($), this._paramU32 = new Uint32Array(this._paramData), this._paramF32 = new Float32Array(this._paramData), this._shaderVersion = -1, this._bindings = [], this._tables = /* @__PURE__ */ new Map(), this.disposed = !1;
420
+ }
421
+ _ensurePipeline() {
422
+ let { wgsl: e, bindings: t, version: n } = Q();
423
+ this._pipeline && this._shaderVersion === n || (this._bindings = t, this._shaderVersion = n, this._pipeline = this.device.createComputePipeline({
424
+ label: this.label,
425
+ layout: "auto",
426
+ compute: {
427
+ module: this.device.createShaderModule({
428
+ label: this.label,
429
+ code: ue(e)
430
+ }),
431
+ entryPoint: "main"
432
+ }
433
+ }));
434
+ }
435
+ _ensureTables() {
436
+ let e = /* @__PURE__ */ new Set();
437
+ for (let { index: t, transform: n } of this._bindings) {
438
+ let { data: r, size: i } = n.table;
439
+ e.add(t);
440
+ let a = this._tables.get(t);
441
+ if (a && a.data === r) continue;
442
+ a?.texture.destroy();
443
+ let o = this.device.createTexture({
444
+ label: `${this.label}-${n.wgslConst}`,
445
+ size: [
446
+ i,
447
+ i,
448
+ i
449
+ ],
450
+ dimension: "3d",
451
+ format: "rgba16float",
452
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
453
+ });
454
+ this.device.queue.writeTexture({ texture: o }, r, {
455
+ bytesPerRow: i * 8,
456
+ rowsPerImage: i
457
+ }, [
458
+ i,
459
+ i,
460
+ i
461
+ ]), this._tables.set(t, {
462
+ texture: o,
463
+ data: r,
464
+ view: o.createView()
465
+ });
466
+ }
467
+ for (let [t, n] of this._tables) e.has(t) || (n.texture.destroy(), this._tables.delete(t));
468
+ }
469
+ ensureSize(e, t) {
470
+ if (this._ensurePipeline(), this._ensureTables(), this.width === e && this.height === t && this._storage) return;
471
+ this._releaseBuffers();
472
+ let n = e * t * 4;
473
+ this._storage = this.device.createBuffer({
474
+ label: `${this.label}-out`,
475
+ size: n,
476
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
477
+ }), this._map = this.device.createBuffer({
478
+ label: `${this.label}-map`,
479
+ size: n,
480
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
481
+ }), this._params = this.device.createBuffer({
482
+ label: `${this.label}-params`,
483
+ size: $,
484
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
485
+ }), this.width = e, this.height = t;
486
+ }
487
+ async toRGBA8(e, { exposure: t = 1, toneMapping: n = 0, saturation: r = 1, flipY: i = !1 } = {}) {
488
+ if (this.disposed) throw Error("PackedToneMapper: disposed");
489
+ if (!this._storage) throw Error("PackedToneMapper: call ensureSize() first");
490
+ this._ensurePipeline(), this._ensureTables();
491
+ let { width: a, height: o } = this;
492
+ this._paramU32[0] = a, this._paramU32[1] = o, this._paramU32[2] = n >>> 0, this._paramU32[3] = +!!i, this._paramF32[4] = t, this._paramF32[5] = r, this.device.queue.writeBuffer(this._params, 0, this._paramData);
493
+ let s = [...this._tables.entries()].map(([e, t]) => ({
494
+ binding: e,
495
+ resource: t.view
496
+ })), c = this.device.createBindGroup({
497
+ layout: this._pipeline.getBindGroupLayout(0),
498
+ entries: [
499
+ ...s,
500
+ {
501
+ binding: 0,
502
+ resource: {
503
+ buffer: e,
504
+ size: a * o * 8
505
+ }
506
+ },
507
+ {
508
+ binding: 1,
509
+ resource: { buffer: this._storage }
510
+ },
511
+ {
512
+ binding: 2,
513
+ resource: { buffer: this._params }
514
+ }
515
+ ]
516
+ }), l = this.device.createCommandEncoder({ label: this.label }), u = l.beginComputePass();
517
+ u.setPipeline(this._pipeline), u.setBindGroup(0, c), u.dispatchWorkgroups(Math.ceil(a / 8), Math.ceil(o / 8)), u.end(), l.copyBufferToBuffer(this._storage, 0, this._map, 0, a * o * 4), this.device.queue.submit([l.finish()]), await this._map.mapAsync(GPUMapMode.READ);
518
+ let d = new Uint8ClampedArray(this._map.getMappedRange().slice(0));
519
+ return this._map.unmap(), d;
520
+ }
521
+ _releaseBuffers() {
522
+ this._storage?.destroy(), this._map?.destroy(), this._params?.destroy(), this._storage = null, this._map = null, this._params = null;
523
+ }
524
+ dispose() {
525
+ if (!this.disposed) {
526
+ this.disposed = !0, this._releaseBuffers();
527
+ for (let e of this._tables.values()) e.texture.destroy();
528
+ this._tables.clear(), this._pipeline = null;
529
+ }
530
+ }
531
+ };
532
+ //#endregion
533
+ export { x as C, C as S, E as T, se as _, H as a, s as b, q as c, K as d, J as f, ie as g, ae as h, F as i, U as l, oe as m, ce as n, Y as o, W as p, I as r, X as s, de as t, G as u, O as v, T as w, S as x, k as y };