rayzee 8.3.0 → 8.4.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.
@@ -0,0 +1,341 @@
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://cdn.jsdelivr.net/npm/denoiser/tzas/",
107
+ upscalerModelBaseUrl: "https://huggingface.co/notaneimu/onnx-image-models/resolve/main/",
108
+ dlssRuntimeUrl: "/dlss/dlss-runtime.js",
109
+ dlssAssetBaseUrl: "https://pub-6e048ff014374f11bef33d76b6c2b5ef.r2.dev/v1",
110
+ cacheNamespace: "rayzee"
111
+ };
112
+ function O(e) {
113
+ e && Object.assign(D, e);
114
+ }
115
+ function k() {
116
+ return { ...D };
117
+ }
118
+ var A = `
119
+ struct Params {
120
+ width: u32,
121
+ height: u32,
122
+ mode: u32,
123
+ flipY: u32,
124
+ exposure: f32,
125
+ saturation: f32,
126
+ };
127
+
128
+ @group(0) @binding(0) var<storage, read> src: array<u32>;
129
+ @group(0) @binding(1) var<storage, read_write> dst: array<u32>;
130
+ @group(0) @binding(2) var<uniform> params: Params;
131
+
132
+ ${`
133
+ const TM_NONE: u32 = ${a}u;
134
+ const TM_LINEAR: u32 = ${r}u;
135
+ const TM_REINHARD: u32 = ${o}u;
136
+ const TM_CINEON: u32 = ${n}u;
137
+ const TM_ACES: u32 = ${e}u;
138
+ const TM_AGX: u32 = ${t}u;
139
+ const TM_NEUTRAL: u32 = ${i}u;
140
+
141
+ fn tm_reinhard( c: vec3<f32> ) -> vec3<f32> {
142
+ return clamp( c / ( c + vec3<f32>( 1.0 ) ), vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );
143
+ }
144
+
145
+ fn tm_cineon( c0: vec3<f32> ) -> vec3<f32> {
146
+ let c = max( c0 - vec3<f32>( 0.004 ), vec3<f32>( 0.0 ) );
147
+ let v = ( c * ( 6.2 * c + vec3<f32>( 0.5 ) ) ) / ( c * ( 6.2 * c + vec3<f32>( 1.7 ) ) + vec3<f32>( 0.06 ) );
148
+ return pow( max( v, vec3<f32>( 0.0 ) ), vec3<f32>( 2.2 ) );
149
+ }
150
+
151
+ fn tm_aces( c0: vec3<f32> ) -> vec3<f32> {
152
+ let c = c0 / 0.6;
153
+ let m_in = mat3x3<f32>(
154
+ vec3<f32>( 0.59719, 0.07600, 0.02840 ),
155
+ vec3<f32>( 0.35458, 0.90834, 0.13383 ),
156
+ vec3<f32>( 0.04823, 0.01566, 0.83777 ) );
157
+ let v = m_in * c;
158
+ let a = v * ( v + vec3<f32>( 0.0245786 ) ) - vec3<f32>( 0.000090537 );
159
+ let b = v * ( 0.983729 * v + vec3<f32>( 0.4329510 ) ) + vec3<f32>( 0.238081 );
160
+ let m_out = mat3x3<f32>(
161
+ vec3<f32>( 1.60475, -0.10208, -0.00327 ),
162
+ vec3<f32>( -0.53108, 1.10813, -0.07276 ),
163
+ vec3<f32>( -0.07367, -0.00605, 1.07602 ) );
164
+ return clamp( m_out * ( a / b ), vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );
165
+ }
166
+
167
+ fn tm_agx( c0: vec3<f32> ) -> vec3<f32> {
168
+ let m_in = mat3x3<f32>(
169
+ vec3<f32>( 0.6274, 0.0691, 0.0164 ),
170
+ vec3<f32>( 0.3293, 0.9195, 0.0880 ),
171
+ vec3<f32>( 0.0433, 0.0113, 0.8956 ) );
172
+ let m_agx = mat3x3<f32>(
173
+ vec3<f32>( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),
174
+ vec3<f32>( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),
175
+ vec3<f32>( 0.0482516061458583, 0.101439036467562, 0.811302368396859 ) );
176
+
177
+ var v = m_agx * ( m_in * c0 );
178
+
179
+ let minEv = -12.47393;
180
+ let maxEv = 4.026069;
181
+ v = clamp( ( log2( max( v, vec3<f32>( 1e-10 ) ) ) - vec3<f32>( minEv ) ) / ( maxEv - minEv ),
182
+ vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );
183
+
184
+ let x2 = v * v;
185
+ let x4 = x2 * x2;
186
+ v = 15.5 * x4 * x2 - 40.14 * x4 * v + 31.96 * x4 - 6.868 * x2 * v + 0.4298 * x2 + 0.1191 * v
187
+ - vec3<f32>( 0.00232 );
188
+
189
+ let m_out = mat3x3<f32>(
190
+ vec3<f32>( 1.1271005818144368, -0.1413297634984383, -0.14132976349843826 ),
191
+ vec3<f32>( -0.11060664309660323, 1.157823702216272, -0.11060664309660294 ),
192
+ vec3<f32>( -0.016493938717834573, -0.016493938717834257, 1.2519364065950405 ) );
193
+ let o = pow( max( m_out * v, vec3<f32>( 0.0 ) ), vec3<f32>( 2.2 ) );
194
+
195
+ let m_srgb = mat3x3<f32>(
196
+ vec3<f32>( 1.6605, -0.1246, -0.0182 ),
197
+ vec3<f32>( -0.5876, 1.1329, -0.1006 ),
198
+ vec3<f32>( -0.0728, -0.0083, 1.1187 ) );
199
+ return clamp( m_srgb * o, vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );
200
+ }
201
+
202
+ fn tm_neutral( c0: vec3<f32> ) -> vec3<f32> {
203
+ let startCompression = 0.8 - 0.04;
204
+ let desaturation = 0.15;
205
+
206
+ let x = min( c0.r, min( c0.g, c0.b ) );
207
+ var offset = 0.04;
208
+ if ( x < 0.08 ) { offset = x - 6.25 * x * x; }
209
+ var c = c0 - vec3<f32>( offset );
210
+
211
+ let peak = max( c.r, max( c.g, c.b ) );
212
+ if ( peak < startCompression ) { return c; }
213
+
214
+ let d = 1.0 - startCompression;
215
+ let newPeak = 1.0 - d * d / ( peak + d - startCompression );
216
+ c = c * ( newPeak / peak );
217
+ let gFactor = 1.0 - 1.0 / ( desaturation * ( peak - newPeak ) + 1.0 );
218
+ return mix( c, vec3<f32>( newPeak ), gFactor );
219
+ }
220
+
221
+ // Three.js clamps the fragment output with max(0) before tone mapping, so the curves never see a
222
+ // negative channel. The saturation grade drives channels below zero on much of a typical frame, and
223
+ // AgX/Neutral mix negatives across channels instead of clipping them.
224
+ fn rayzee_tone_curve( color: vec3<f32>, mode: u32 ) -> vec3<f32> {
225
+ let c = max( color, vec3<f32>( 0.0 ) );
226
+ if ( mode == TM_REINHARD ) { return tm_reinhard( c ); }
227
+ if ( mode == TM_CINEON ) { return tm_cineon( c ); }
228
+ if ( mode == TM_ACES ) { return tm_aces( c ); }
229
+ if ( mode == TM_AGX ) { return tm_agx( c ); }
230
+ if ( mode == TM_NEUTRAL ) { return tm_neutral( c ); }
231
+ return clamp( c, vec3<f32>( 0.0 ), vec3<f32>( 1.0 ) );
232
+ }
233
+
234
+ fn rayzee_tone_map( linearRGB: vec3<f32>, mode: u32, exposure: f32, saturation: f32 ) -> vec3<f32> {
235
+ // Three.js returns early for NoToneMapping without applying exposure, so a readback that applied
236
+ // it would paint brighter than the viewport it replaces.
237
+ var c = linearRGB * select( exposure, 1.0, mode == TM_NONE );
238
+ if ( saturation != 1.0 ) {
239
+ let luma = vec3<f32>( dot( c, vec3<f32>( 0.2126, 0.7152, 0.0722 ) ) );
240
+ c = luma + ( c - luma ) * saturation;
241
+ }
242
+ return rayzee_tone_curve( c, mode );
243
+ }
244
+
245
+ fn rayzee_linear_to_srgb( c: vec3<f32> ) -> vec3<f32> {
246
+ return select(
247
+ 1.055 * pow( max( c, vec3<f32>( 0.0 ) ), vec3<f32>( 1.0 / 2.4 ) ) - vec3<f32>( 0.055 ),
248
+ 12.92 * c,
249
+ c <= vec3<f32>( 0.0031308 ) );
250
+ }
251
+
252
+ fn rayzee_to_u8( srgb: vec3<f32> ) -> vec3<u32> {
253
+ return vec3<u32>( clamp( round( srgb * 255.0 + vec3<f32>( 0.5 ) ), vec3<f32>( 0.0 ), vec3<f32>( 255.0 ) ) );
254
+ }
255
+ `}
256
+
257
+ @compute @workgroup_size(8, 8)
258
+ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
259
+ if ( gid.x >= params.width || gid.y >= params.height ) { return; }
260
+
261
+ var srcY = gid.y;
262
+ if ( params.flipY == 1u ) { srcY = params.height - 1u - gid.y; }
263
+
264
+ let a = ( srcY * params.width + gid.x ) * 2u;
265
+ let rg = unpack2x16float( src[ a ] );
266
+ let ba = unpack2x16float( src[ a + 1u ] );
267
+
268
+ let mapped = rayzee_tone_map( vec3<f32>( rg.x, rg.y, ba.x ), params.mode, params.exposure, params.saturation );
269
+ let b8 = rayzee_to_u8( rayzee_linear_to_srgb( mapped ) );
270
+ dst[ gid.y * params.width + gid.x ] = b8.x | ( b8.y << 8u ) | ( b8.z << 16u ) | ( 255u << 24u );
271
+ }
272
+ `, j = 32, M = class {
273
+ constructor(e, t = "rayzee:tonemap") {
274
+ 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(j), this._paramU32 = new Uint32Array(this._paramData), this._paramF32 = new Float32Array(this._paramData), this.disposed = !1;
275
+ }
276
+ ensureSize(e, t) {
277
+ if (this.width === e && this.height === t && this._pipeline) return;
278
+ this._releaseBuffers();
279
+ let n = e * t * 4;
280
+ this._storage = this.device.createBuffer({
281
+ label: `${this.label}-out`,
282
+ size: n,
283
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
284
+ }), this._map = this.device.createBuffer({
285
+ label: `${this.label}-map`,
286
+ size: n,
287
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
288
+ }), this._params = this.device.createBuffer({
289
+ label: `${this.label}-params`,
290
+ size: j,
291
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
292
+ }), this._pipeline ??= this.device.createComputePipeline({
293
+ label: this.label,
294
+ layout: "auto",
295
+ compute: {
296
+ module: this.device.createShaderModule({
297
+ label: this.label,
298
+ code: A
299
+ }),
300
+ entryPoint: "main"
301
+ }
302
+ }), this.width = e, this.height = t;
303
+ }
304
+ async toRGBA8(e, { exposure: t = 1, toneMapping: n = 0, saturation: r = 1, flipY: i = !1 } = {}) {
305
+ if (this.disposed) throw Error("PackedToneMapper: disposed");
306
+ if (!this._pipeline) throw Error("PackedToneMapper: call ensureSize() first");
307
+ let { width: a, height: o } = this;
308
+ 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);
309
+ let s = this.device.createBindGroup({
310
+ layout: this._pipeline.getBindGroupLayout(0),
311
+ entries: [
312
+ {
313
+ binding: 0,
314
+ resource: {
315
+ buffer: e,
316
+ size: a * o * 8
317
+ }
318
+ },
319
+ {
320
+ binding: 1,
321
+ resource: { buffer: this._storage }
322
+ },
323
+ {
324
+ binding: 2,
325
+ resource: { buffer: this._params }
326
+ }
327
+ ]
328
+ }), c = this.device.createCommandEncoder({ label: this.label }), l = c.beginComputePass();
329
+ l.setPipeline(this._pipeline), l.setBindGroup(0, s), l.dispatchWorkgroups(Math.ceil(a / 8), Math.ceil(o / 8)), l.end(), c.copyBufferToBuffer(this._storage, 0, this._map, 0, a * o * 4), this.device.queue.submit([c.finish()]), await this._map.mapAsync(GPUMapMode.READ);
330
+ let u = new Uint8ClampedArray(this._map.getMappedRange().slice(0));
331
+ return this._map.unmap(), u;
332
+ }
333
+ _releaseBuffers() {
334
+ this._storage?.destroy(), this._map?.destroy(), this._params?.destroy(), this._storage = null, this._map = null, this._params = null;
335
+ }
336
+ dispose() {
337
+ this.disposed || (this.disposed = !0, this._releaseBuffers(), this._pipeline = null);
338
+ }
339
+ };
340
+ //#endregion
341
+ export { S as a, T as c, s as i, E as l, O as n, C as o, k as r, x as s, M as t };