@voluma/vlam 0.3.2 → 0.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.
Files changed (40) hide show
  1. package/README.md +2 -2
  2. package/dist/core/compute-sorter.d.ts +7 -1
  3. package/dist/core/index.d.ts +2 -2
  4. package/dist/core/radix-sorter.d.ts +6 -0
  5. package/dist/core/sort-worker-protocol.d.ts +2 -0
  6. package/dist/core/sorter.d.ts +4 -4
  7. package/dist/core/splat-mesh-types.d.ts +22 -5
  8. package/dist/core/splat-mesh.d.ts +11 -2
  9. package/dist/core/splat-sort-bounds.d.ts +17 -0
  10. package/dist/core/worker-sorter.d.ts +7 -5
  11. package/dist/formats/lcc.js +276 -277
  12. package/dist/formats/lcc.js.map +1 -1
  13. package/dist/formats/rad/index.d.ts +1 -1
  14. package/dist/formats/rad/parse-rad.d.ts +1 -1
  15. package/dist/formats/rad.js.map +1 -1
  16. package/dist/index.js +3 -3
  17. package/dist/lod-scheduler-ChoZyEeq.js +466 -0
  18. package/dist/lod-scheduler-ChoZyEeq.js.map +1 -0
  19. package/dist/radix-sorter-tSffmerk.js +181 -0
  20. package/dist/radix-sorter-tSffmerk.js.map +1 -0
  21. package/dist/relighting-qaANKC4Z.js +997 -0
  22. package/dist/relighting-qaANKC4Z.js.map +1 -0
  23. package/dist/{splat-mesh-CsLOQb08.js → splat-mesh-B1KlWHvx.js} +545 -513
  24. package/dist/splat-mesh-B1KlWHvx.js.map +1 -0
  25. package/dist/splat-mesh-types-BZIko-_9.js.map +1 -1
  26. package/dist/static-lod.js +1 -1
  27. package/dist/streaming/lod-scheduler.d.ts +32 -0
  28. package/dist/streaming/lod-source.d.ts +15 -9
  29. package/dist/streaming/streamed-splat-mesh.d.ts +38 -22
  30. package/dist/streaming.js +959 -927
  31. package/dist/streaming.js.map +1 -1
  32. package/dist/unified.js +17 -17
  33. package/package.json +1 -1
  34. package/dist/lod-scheduler-B0a_uBlv.js +0 -383
  35. package/dist/lod-scheduler-B0a_uBlv.js.map +0 -1
  36. package/dist/radix-sorter-BrbUg_CV.js +0 -178
  37. package/dist/radix-sorter-BrbUg_CV.js.map +0 -1
  38. package/dist/relighting-Tiwep8yd.js +0 -977
  39. package/dist/relighting-Tiwep8yd.js.map +0 -1
  40. package/dist/splat-mesh-CsLOQb08.js.map +0 -1
@@ -1,178 +0,0 @@
1
- var Dt = Object.defineProperty;
2
- var Ot = (u, n, e) => n in u ? Dt(u, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : u[n] = e;
3
- var r = (u, n, e) => Ot(u, typeof n != "symbol" ? n + "" : n, e);
4
- import * as h from "three/webgpu";
5
- import { uniform as z, storage as m, Fn as A, If as l, float as C, instanceIndex as i, ivec2 as Mt, int as G, textureLoad as Kt, floatBitsToUint as Vt, uint as t, atomicStore as D, workgroupId as tt, Loop as B, invocationLocalIndex as bt, atomicAdd as Lt, atomicLoad as I, workgroupArray as Pt, storageBarrier as H, workgroupBarrier as q, atomicOr as Wt, countOneBits as et } from "three/tsl";
6
- import { S as Xt, v as Nt, r as zt } from "./relighting-Tiwep8yd.js";
7
- const Rt = 24, Gt = 32, nt = 4, xt = (1 << Rt) - 1;
8
- function Ht(u) {
9
- if (!Number.isInteger(u) || u <= 0 || u % nt !== 0)
10
- throw new RangeError("Radix key width must be a positive multiple of four bits.");
11
- return u / nt;
12
- }
13
- const c = 256, it = 8, st = c * it, O = 16, _ = c / 32, Y = O * _, Z = 256;
14
- class jt {
15
- constructor(n) {
16
- r(this, "kind", "radix");
17
- r(this, "renderer");
18
- r(this, "stages", []);
19
- r(this, "workingAttributes");
20
- /** Frees the JS mirrors three keeps behind the GPU-only ping-pong buffers. */
21
- r(this, "mirrors");
22
- /** Set by {@link dispose}; makes a second dispose a no-op. */
23
- r(this, "disposed", !1);
24
- r(this, "viewRow2", z(new h.Vector4()));
25
- r(this, "depthMin", z(0));
26
- r(this, "depthScale", z(0));
27
- r(this, "activeCount", z(0));
28
- r(this, "viewCenter", new h.Vector3());
29
- /** Exact mode avoids scene-bounds quantization entirely. */
30
- r(this, "exactDepth");
31
- const { capacity: e, centersTexture: f, dataTextureWidth: g, centersBuffer: v } = n;
32
- if (!f && !v)
33
- throw new Error("RadixSorter: provide centersTexture or centersBuffer.");
34
- if (f && g === void 0)
35
- throw new Error("RadixSorter: dataTextureWidth is required with centersTexture.");
36
- this.renderer = n.renderer;
37
- const S = n.exactDepth === !0;
38
- this.exactDepth = S;
39
- const F = Ht(S ? Gt : Rt), p = Math.ceil(e / st), k = O * p, M = Math.ceil(k / Z), rt = new h.StorageBufferAttribute(new Uint32Array(e), 1), ot = new h.StorageBufferAttribute(new Uint32Array(e), 1), at = new h.StorageBufferAttribute(new Uint32Array(e), 1), ct = new h.StorageBufferAttribute(new Uint32Array(e), 1), ut = new h.StorageBufferAttribute(
40
- new Uint32Array(k),
41
- 1
42
- ), dt = new h.StorageBufferAttribute(new Uint32Array(M), 1), lt = new h.StorageBufferAttribute(
43
- new Uint32Array(p * Y),
44
- 1
45
- );
46
- this.workingAttributes = [
47
- rt,
48
- ot,
49
- at,
50
- ct,
51
- ut,
52
- dt,
53
- lt
54
- ], this.mirrors = new Xt(this.workingAttributes);
55
- const K = m(rt, "uint", e), mt = m(ot, "uint", e), V = m(at, "uint", e), ht = m(ct, "uint", e), vt = m(n.sourceIndexAttribute, "uint", e), St = m(n.splatIndexAttribute, "float", e), gt = v ? m(v, "vec4", e) : null, w = m(ut, "uint", k).toAtomic(), L = m(dt, "uint", M), T = m(lt, "uint", p * Y).toAtomic(), kt = A(() => {
56
- l(C(i).lessThan(this.activeCount), () => {
57
- const o = vt.element(i), P = f ? Mt(
58
- G(o).mod(G(g)),
59
- G(o).div(G(g))
60
- ) : null, j = gt ? gt.element(o).xyz : Kt(f, P).xyz, W = this.viewRow2.xyz.dot(j).add(this.viewRow2.w);
61
- if (S) {
62
- const X = Vt(W), N = X.shiftRight(t(31)).equal(t(0)).select(t(2147483648), t(4294967295));
63
- K.element(i).assign(X.bitXor(N));
64
- } else
65
- K.element(i).assign(W.sub(this.depthMin).mul(this.depthScale).clamp(0, xt).toUint());
66
- V.element(i).assign(o);
67
- });
68
- })().compute(e, [c]);
69
- this.stages.push(kt);
70
- for (let o = 0; o < F; o++) {
71
- const P = o % 2 === 0 ? K : mt, j = o % 2 === 0 ? mt : K, W = o % 2 === 0 ? V : ht, X = o % 2 === 0 ? ht : V, N = t(o * nt), Bt = A(() => {
72
- D(w.element(i), t(0));
73
- })().compute(k, [c]), It = A(() => {
74
- const s = tt.x.mul(t(st));
75
- B(it, ({ i: a }) => {
76
- const d = s.add(t(a).mul(t(c))).add(bt);
77
- l(C(d).lessThan(this.activeCount), () => {
78
- const b = P.element(d).shiftRight(N).bitAnd(t(15));
79
- Lt(w.element(b.mul(t(p)).add(tt.x)), t(1));
80
- });
81
- });
82
- })().compute(p * c, [c]), _t = A(() => {
83
- const s = i.mul(t(Z)), a = t(0).toVar();
84
- B(Z, ({ i: d }) => {
85
- const b = s.add(t(d));
86
- l(b.lessThan(t(k)), () => {
87
- const E = I(w.element(b)).toVar();
88
- D(w.element(b), a), a.addAssign(E);
89
- });
90
- }), L.element(i).assign(a);
91
- })().compute(M, [64]), Et = A(() => {
92
- l(i.equal(t(0)), () => {
93
- const s = t(0).toVar();
94
- B(M, ({ i: a }) => {
95
- const d = L.element(a).toVar();
96
- L.element(a).assign(s), s.addAssign(d);
97
- });
98
- });
99
- })().compute(1, [64]), yt = A(() => {
100
- const s = i.div(t(Z));
101
- D(
102
- w.element(i),
103
- I(w.element(i)).add(L.element(s))
104
- );
105
- })().compute(k, [c]), J = Pt("uint", O), Ut = A(() => {
106
- const s = bt, a = tt.x, d = a.mul(t(Y));
107
- l(s.lessThan(t(O)), () => {
108
- J.element(s).assign(t(0));
109
- }), l(s.lessThan(t(Y)), () => {
110
- D(T.element(d.add(s)), t(0));
111
- }), H(), q(), B(it, ({ i: b }) => {
112
- const E = a.mul(t(st)).add(b.toUint().mul(t(c))).add(s), At = C(E).lessThan(this.activeCount), Q = t(0).toVar(), ft = t(0).toVar(), y = t(0).toVar();
113
- l(At, () => {
114
- Q.assign(P.element(E)), ft.assign(W.element(E)), y.assign(Q.shiftRight(N).bitAnd(t(15)));
115
- const x = s.shiftRight(t(5)), U = s.bitAnd(t(31)), R = d.add(y.mul(t(_))).add(x);
116
- Wt(T.element(R), t(1).shiftLeft(U));
117
- }), H(), q(), l(At, () => {
118
- const x = s.shiftRight(t(5)), U = s.bitAnd(t(31)), R = d.add(y.mul(t(_))), $ = J.element(y).toVar();
119
- B(_, ({ i: wt }) => {
120
- l(t(wt).lessThan(x), () => {
121
- $.addAssign(
122
- et(I(T.element(R.add(wt.toUint()))))
123
- );
124
- });
125
- });
126
- const Ct = t(1).shiftLeft(U).sub(t(1));
127
- $.addAssign(
128
- et(I(T.element(R.add(x))).bitAnd(Ct))
129
- );
130
- const pt = I(w.element(y.mul(t(p)).add(a))).add($);
131
- j.element(pt).assign(Q), X.element(pt).assign(ft);
132
- }), H(), q(), l(s.lessThan(t(O)), () => {
133
- const x = t(0).toVar();
134
- B(_, ({ i: U }) => {
135
- const R = d.add(s.mul(t(_))).add(U.toUint());
136
- x.addAssign(et(I(T.element(R)))), D(T.element(R), t(0));
137
- }), J.element(s).addAssign(x);
138
- }), H(), q();
139
- });
140
- })().compute(p * c, [c]);
141
- this.stages.push(
142
- Bt,
143
- It,
144
- _t,
145
- Et,
146
- yt,
147
- Ut
148
- );
149
- }
150
- const Tt = A(() => {
151
- l(C(i).lessThan(this.activeCount), () => {
152
- St.element(i).assign(C(V.element(i)));
153
- });
154
- })().compute(e, [c]);
155
- this.stages.push(Tt);
156
- }
157
- sort(n, e, f) {
158
- if (e === 0) return !0;
159
- const g = n.elements;
160
- if (this.viewRow2.value.set(g[2], g[6], g[10], g[14]), this.activeCount.value = e, !this.exactDepth) {
161
- this.viewCenter.copy(f.center).applyMatrix4(n);
162
- const v = Nt(n, f.radius), S = this.viewCenter.z - v, F = this.viewCenter.z + v;
163
- this.depthMin.value = S, this.depthScale.value = xt / (F - S || 1);
164
- }
165
- return this.stages[0].count = e, this.stages[this.stages.length - 1].count = e, this.renderer.compute(this.stages), this.mirrors.settled || this.mirrors.release(this.renderer), !0;
166
- }
167
- dispose() {
168
- if (!this.disposed) {
169
- this.disposed = !0;
170
- for (const n of this.stages) n.dispose();
171
- zt(this.renderer, this.workingAttributes);
172
- }
173
- }
174
- }
175
- export {
176
- jt as RadixSorter
177
- };
178
- //# sourceMappingURL=radix-sorter-BrbUg_CV.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"radix-sorter-BrbUg_CV.js","sources":["../src/lib/core/radix-sort.ts","../src/lib/core/radix-sorter.ts"],"sourcesContent":["/**\n * @role Utility\n * Shared constants and deterministic reference logic for GPU radix sorting.\n */\n\n/** Depth precision retained by both the GPU radix path and WebGL worker path. */\nexport const RADIX_KEY_BITS = 24;\n/** Exact Float32 depth keys use every sortable IEEE-754 bit. */\nexport const RADIX_EXACT_KEY_BITS = 32;\n/** Four-bit digits keep the portable shader's workgroup memory requirements small. */\nexport const RADIX_BITS_PER_PASS = 4;\nexport const RADIX_BUCKETS = 1 << RADIX_BITS_PER_PASS;\nexport const RADIX_PASS_COUNT = RADIX_KEY_BITS / RADIX_BITS_PER_PASS;\nexport const RADIX_KEY_MAX = (1 << RADIX_KEY_BITS) - 1;\n\n/** Number of four-bit passes required for one unsigned radix key width. */\nexport function radixPassCount(keyBits: number): number {\n if (!Number.isInteger(keyBits) || keyBits <= 0 || keyBits % RADIX_BITS_PER_PASS !== 0) {\n throw new RangeError('Radix key width must be a positive multiple of four bits.');\n }\n return keyBits / RADIX_BITS_PER_PASS;\n}\n\n/**\n * Maps a Float32 bit pattern onto unsigned integer order without losing depth\n * precision. Ascending mapped keys are ascending numeric floats, including\n * negative view-space Z values (farther splats first in VLAM's convention).\n */\nexport function sortableFloat32Bits(bits: number): number {\n const value = bits >>> 0;\n return (value ^ ((value & 0x80000000) === 0 ? 0x80000000 : 0xffffffff)) >>> 0;\n}\n\n/** Quantizes a depth into the unsigned 24-bit key used by the GPU sorter. */\nexport function quantizeDepthKey(depth: number, minimum: number, maximum: number): number {\n const span = maximum - minimum;\n if (!Number.isFinite(depth) || !Number.isFinite(span) || span <= 0) return 0;\n return Math.min(\n RADIX_KEY_MAX,\n Math.max(0, Math.round(((depth - minimum) / span) * RADIX_KEY_MAX)),\n );\n}\n\n/**\n * Stable CPU reference for validating the GPU's six four-bit radix passes.\n * This is deliberately test/debug-only logic, not the WebGL production sorter.\n */\nexport function stableRadixSortReference(\n keys: Uint32Array,\n values?: Uint32Array,\n keyBits = RADIX_KEY_BITS,\n): Uint32Array {\n const count = keys.length;\n let inputKeys = Uint32Array.from(keys);\n let outputKeys = new Uint32Array(count);\n let inputValues = values ? Uint32Array.from(values) : Uint32Array.from(keys.keys());\n let outputValues = new Uint32Array(count);\n const counts = new Uint32Array(RADIX_BUCKETS);\n const offsets = new Uint32Array(RADIX_BUCKETS);\n\n for (let pass = 0; pass < radixPassCount(keyBits); pass++) {\n counts.fill(0);\n const shift = pass * RADIX_BITS_PER_PASS;\n for (let i = 0; i < count; i++) {\n const digit = ((inputKeys[i] as number) >>> shift) & 0xf;\n counts[digit] = (counts[digit] as number) + 1;\n }\n let total = 0;\n for (let digit = 0; digit < RADIX_BUCKETS; digit++) {\n offsets[digit] = total;\n total += counts[digit] as number;\n }\n for (let i = 0; i < count; i++) {\n const key = inputKeys[i] as number;\n const digit = (key >>> shift) & 0xf;\n const target = offsets[digit] as number;\n offsets[digit] = target + 1;\n outputKeys[target] = key;\n outputValues[target] = inputValues[i] as number;\n }\n [inputKeys, outputKeys] = [outputKeys, inputKeys];\n [inputValues, outputValues] = [outputValues, inputValues];\n }\n return inputValues;\n}\n","/**\n * @role Bridge\n * Portable stable WebGPU radix sorting adapted to Three.js TSL compute nodes.\n */\nimport * as THREE from 'three/webgpu';\nimport {\n Fn,\n If,\n Loop,\n atomicAdd,\n atomicLoad,\n atomicOr,\n atomicStore,\n countOneBits,\n float,\n floatBitsToUint,\n instanceIndex,\n int,\n invocationLocalIndex,\n ivec2,\n storage,\n storageBarrier,\n textureLoad,\n uint,\n uniform,\n workgroupArray,\n workgroupBarrier,\n workgroupId,\n} from 'three/tsl';\nimport type { SplatSorter } from './sorter';\nimport { releaseRendererAttributes } from './compute-sorter';\nimport {\n RADIX_BITS_PER_PASS,\n RADIX_EXACT_KEY_BITS,\n RADIX_KEY_BITS,\n RADIX_KEY_MAX,\n radixPassCount,\n} from './radix-sort';\nimport { viewDepthRadius } from './splat-sort-bounds';\nimport { StorageMirrorReleaser } from './storage-attribute-mirror';\n\nconst WORKGROUP_SIZE = 256;\nconst ELEMENTS_PER_THREAD = 8;\nconst ELEMENTS_PER_WORKGROUP = WORKGROUP_SIZE * ELEMENTS_PER_THREAD;\nconst DIGIT_COUNT = 16;\nconst MASK_WORDS_PER_DIGIT = WORKGROUP_SIZE / 32;\nconst MASK_WORDS_PER_GROUP = DIGIT_COUNT * MASK_WORDS_PER_DIGIT;\nconst SCAN_BLOCK_SIZE = 256;\n\ntype UintWorkgroupArray = {\n element(index: THREE.Node<'uint'>): THREE.Node<'uint'>;\n};\n\n/** Isolates gaps in Three's current WorkgroupInfo/Bitcount TypeScript declarations. */\nfunction asUintNode(node: unknown): THREE.Node<'uint'> {\n return node as THREE.Node<'uint'>;\n}\n\n/**\n * Stable four-bit-per-pass WebGPU radix sorter.\n *\n * The ranked scatter follows PlayCanvas/WebGPU-Radix-Sort's per-digit bitmask\n * design. Three.js does not currently expose atomic workgroup arrays in TSL,\n * so masks use disjoint global-storage slices per workgroup. Workgroup and\n * storage barriers retain the same stable ranking semantics without relying\n * on cross-workgroup execution order.\n */\nexport class RadixSorter implements SplatSorter {\n readonly kind = 'radix' as const;\n private readonly renderer: THREE.WebGPURenderer;\n private readonly stages: THREE.ComputeNode[] = [];\n private readonly workingAttributes: THREE.StorageBufferAttribute[];\n /** Frees the JS mirrors three keeps behind the GPU-only ping-pong buffers. */\n private readonly mirrors: StorageMirrorReleaser;\n /** Set by {@link dispose}; makes a second dispose a no-op. */\n private disposed = false;\n private readonly viewRow2 = uniform(new THREE.Vector4());\n private readonly depthMin = uniform(0);\n private readonly depthScale = uniform(0);\n private readonly activeCount = uniform(0);\n private readonly viewCenter = new THREE.Vector3();\n /** Exact mode avoids scene-bounds quantization entirely. */\n private readonly exactDepth: boolean;\n\n constructor(options: {\n renderer: THREE.WebGPURenderer;\n capacity: number;\n centersTexture?: THREE.DataTexture;\n dataTextureWidth?: number;\n /** Gathered world-space centers for a unified renderer. */\n centersBuffer?: THREE.StorageBufferAttribute;\n splatIndexAttribute: THREE.StorageInstancedBufferAttribute;\n sourceIndexAttribute: THREE.StorageBufferAttribute;\n /** Keep every Float32 depth bit instead of quantizing to 24 bits. */\n exactDepth?: boolean;\n }) {\n const { capacity, centersTexture, dataTextureWidth, centersBuffer } = options;\n if (!centersTexture && !centersBuffer) {\n throw new Error('RadixSorter: provide centersTexture or centersBuffer.');\n }\n if (centersTexture && dataTextureWidth === undefined) {\n throw new Error('RadixSorter: dataTextureWidth is required with centersTexture.');\n }\n this.renderer = options.renderer;\n const exactDepth = options.exactDepth === true;\n this.exactDepth = exactDepth;\n const passCount = radixPassCount(exactDepth ? RADIX_EXACT_KEY_BITS : RADIX_KEY_BITS);\n const groupCount = Math.ceil(capacity / ELEMENTS_PER_WORKGROUP);\n const histogramLength = DIGIT_COUNT * groupCount;\n const scanBlockCount = Math.ceil(histogramLength / SCAN_BLOCK_SIZE);\n\n const keysAAttribute = new THREE.StorageBufferAttribute(new Uint32Array(capacity), 1);\n const keysBAttribute = new THREE.StorageBufferAttribute(new Uint32Array(capacity), 1);\n const valuesAAttribute = new THREE.StorageBufferAttribute(new Uint32Array(capacity), 1);\n const valuesBAttribute = new THREE.StorageBufferAttribute(new Uint32Array(capacity), 1);\n const histogramAttribute = new THREE.StorageBufferAttribute(\n new Uint32Array(histogramLength),\n 1,\n );\n const scanSumsAttribute = new THREE.StorageBufferAttribute(new Uint32Array(scanBlockCount), 1);\n const masksAttribute = new THREE.StorageBufferAttribute(\n new Uint32Array(groupCount * MASK_WORDS_PER_GROUP),\n 1,\n );\n this.workingAttributes = [\n keysAAttribute,\n keysBAttribute,\n valuesAAttribute,\n valuesBAttribute,\n histogramAttribute,\n scanSumsAttribute,\n masksAttribute,\n ];\n this.mirrors = new StorageMirrorReleaser(this.workingAttributes);\n\n const keysA = storage(keysAAttribute, 'uint', capacity);\n const keysB = storage(keysBAttribute, 'uint', capacity);\n const valuesA = storage(valuesAAttribute, 'uint', capacity);\n const valuesB = storage(valuesBAttribute, 'uint', capacity);\n const source = storage(options.sourceIndexAttribute, 'uint', capacity);\n const order = storage(options.splatIndexAttribute, 'float', capacity);\n const workCenters = centersBuffer ? storage(centersBuffer, 'vec4', capacity) : null;\n const histogram = storage(histogramAttribute, 'uint', histogramLength).toAtomic();\n const scanSums = storage(scanSumsAttribute, 'uint', scanBlockCount);\n const masks = storage(masksAttribute, 'uint', groupCount * MASK_WORDS_PER_GROUP).toAtomic();\n\n const buildKeys = Fn(() => {\n If(float(instanceIndex).lessThan(this.activeCount), () => {\n const poolIndex = source.element(instanceIndex);\n const texel = centersTexture\n ? ivec2(\n int(poolIndex).mod(int(dataTextureWidth as number)),\n int(poolIndex).div(int(dataTextureWidth as number)),\n )\n : null;\n const center = workCenters\n ? workCenters.element(poolIndex).xyz\n : textureLoad(centersTexture, texel as THREE.Node<'ivec2'>).xyz;\n const depth = this.viewRow2.xyz.dot(center).add(this.viewRow2.w);\n if (exactDepth) {\n // IEEE-754 bits are monotonic only for positive values. Flip the\n // sign partition so ascending unsigned keys remain ascending numeric\n // depth, including VLAM's negative view-space Z convention.\n // Three's BitcastNode typings omit shift/xor; runtime nodes support them.\n const bits = asUintNode(floatBitsToUint(depth));\n const mask = bits\n .shiftRight(uint(31))\n .equal(uint(0))\n .select(uint(0x80000000), uint(0xffffffff));\n keysA.element(instanceIndex).assign(bits.bitXor(mask));\n } else {\n keysA\n .element(instanceIndex)\n .assign(depth.sub(this.depthMin).mul(this.depthScale).clamp(0, RADIX_KEY_MAX).toUint());\n }\n valuesA.element(instanceIndex).assign(poolIndex);\n });\n })().compute(capacity, [WORKGROUP_SIZE]);\n this.stages.push(buildKeys);\n\n for (let pass = 0; pass < passCount; pass++) {\n const inputKeys = pass % 2 === 0 ? keysA : keysB;\n const outputKeys = pass % 2 === 0 ? keysB : keysA;\n const inputValues = pass % 2 === 0 ? valuesA : valuesB;\n const outputValues = pass % 2 === 0 ? valuesB : valuesA;\n const bit = uint(pass * RADIX_BITS_PER_PASS);\n\n const clearHistogram = Fn(() => {\n atomicStore(histogram.element(instanceIndex), uint(0));\n })().compute(histogramLength, [WORKGROUP_SIZE]);\n\n const buildHistogram = Fn(() => {\n const base = workgroupId.x.mul(uint(ELEMENTS_PER_WORKGROUP));\n Loop(ELEMENTS_PER_THREAD, ({ i }) => {\n const index = base.add(uint(i).mul(uint(WORKGROUP_SIZE))).add(invocationLocalIndex);\n If(float(index).lessThan(this.activeCount), () => {\n const digit = inputKeys.element(index).shiftRight(bit).bitAnd(uint(0xf));\n atomicAdd(histogram.element(digit.mul(uint(groupCount)).add(workgroupId.x)), uint(1));\n });\n });\n })().compute(groupCount * WORKGROUP_SIZE, [WORKGROUP_SIZE]);\n\n const scanBlocks = Fn(() => {\n const start = instanceIndex.mul(uint(SCAN_BLOCK_SIZE));\n const running = uint(0).toVar();\n Loop(SCAN_BLOCK_SIZE, ({ i }) => {\n const index = start.add(uint(i));\n If(index.lessThan(uint(histogramLength)), () => {\n const value = atomicLoad(histogram.element(index)).toVar();\n atomicStore(histogram.element(index), running);\n running.addAssign(value);\n });\n });\n scanSums.element(instanceIndex).assign(running);\n })().compute(scanBlockCount, [64]);\n\n const scanBlockSums = Fn(() => {\n If(instanceIndex.equal(uint(0)), () => {\n const running = uint(0).toVar();\n Loop(scanBlockCount, ({ i }) => {\n const value = scanSums.element(i).toVar();\n scanSums.element(i).assign(running);\n running.addAssign(value);\n });\n });\n })().compute(1, [64]);\n\n const addBlockOffsets = Fn(() => {\n const block = instanceIndex.div(uint(SCAN_BLOCK_SIZE));\n atomicStore(\n histogram.element(instanceIndex),\n atomicLoad(histogram.element(instanceIndex)).add(scanSums.element(block)),\n );\n })().compute(histogramLength, [WORKGROUP_SIZE]);\n\n const digitOffsets = workgroupArray('uint', DIGIT_COUNT) as unknown as UintWorkgroupArray;\n const rankedScatter = Fn(() => {\n const thread = invocationLocalIndex;\n const group = workgroupId.x;\n const maskBase = group.mul(uint(MASK_WORDS_PER_GROUP));\n If(thread.lessThan(uint(DIGIT_COUNT)), () => {\n digitOffsets.element(thread).assign(uint(0));\n });\n If(thread.lessThan(uint(MASK_WORDS_PER_GROUP)), () => {\n atomicStore(masks.element(maskBase.add(thread)), uint(0));\n });\n storageBarrier();\n workgroupBarrier();\n\n Loop(ELEMENTS_PER_THREAD, ({ i }) => {\n const index = group\n .mul(uint(ELEMENTS_PER_WORKGROUP))\n .add(i.toUint().mul(uint(WORKGROUP_SIZE)))\n .add(thread);\n const valid = float(index).lessThan(this.activeCount);\n const key = uint(0).toVar();\n const value = uint(0).toVar();\n const digit = uint(0).toVar();\n If(valid, () => {\n key.assign(inputKeys.element(index));\n value.assign(inputValues.element(index));\n digit.assign(key.shiftRight(bit).bitAnd(uint(0xf)));\n const word = thread.shiftRight(uint(5));\n const bitInWord = thread.bitAnd(uint(31));\n const maskIndex = maskBase.add(digit.mul(uint(MASK_WORDS_PER_DIGIT))).add(word);\n atomicOr(masks.element(maskIndex), uint(1).shiftLeft(bitInWord));\n });\n storageBarrier();\n workgroupBarrier();\n\n If(valid, () => {\n const word = thread.shiftRight(uint(5));\n const bitInWord = thread.bitAnd(uint(31));\n const digitBase = maskBase.add(digit.mul(uint(MASK_WORDS_PER_DIGIT)));\n const localRank = digitOffsets.element(digit).toVar();\n Loop(MASK_WORDS_PER_DIGIT, ({ i: wordIndex }) => {\n If(uint(wordIndex).lessThan(word), () => {\n localRank.addAssign(\n asUintNode(\n countOneBits(atomicLoad(masks.element(digitBase.add(wordIndex.toUint())))),\n ),\n );\n });\n });\n const precedingMask = uint(1).shiftLeft(bitInWord).sub(uint(1));\n localRank.addAssign(\n asUintNode(\n countOneBits(atomicLoad(masks.element(digitBase.add(word))).bitAnd(precedingMask)),\n ),\n );\n const prefix = atomicLoad(histogram.element(digit.mul(uint(groupCount)).add(group)));\n const target = prefix.add(localRank);\n outputKeys.element(target).assign(key);\n outputValues.element(target).assign(value);\n });\n\n storageBarrier();\n workgroupBarrier();\n If(thread.lessThan(uint(DIGIT_COUNT)), () => {\n const total = uint(0).toVar();\n Loop(MASK_WORDS_PER_DIGIT, ({ i: wordIndex }) => {\n const maskIndex = maskBase\n .add(thread.mul(uint(MASK_WORDS_PER_DIGIT)))\n .add(wordIndex.toUint());\n total.addAssign(asUintNode(countOneBits(atomicLoad(masks.element(maskIndex)))));\n atomicStore(masks.element(maskIndex), uint(0));\n });\n digitOffsets.element(thread).addAssign(total);\n });\n storageBarrier();\n workgroupBarrier();\n });\n })().compute(groupCount * WORKGROUP_SIZE, [WORKGROUP_SIZE]);\n\n this.stages.push(\n clearHistogram,\n buildHistogram,\n scanBlocks,\n scanBlockSums,\n addBlockOffsets,\n rankedScatter,\n );\n }\n\n const writeOrder = Fn(() => {\n If(float(instanceIndex).lessThan(this.activeCount), () => {\n order.element(instanceIndex).assign(float(valuesA.element(instanceIndex)));\n });\n })().compute(capacity, [WORKGROUP_SIZE]);\n this.stages.push(writeOrder);\n }\n\n sort(modelView: THREE.Matrix4, activeCount: number, bounds: THREE.Sphere): boolean {\n if (activeCount === 0) return true;\n const m = modelView.elements;\n this.viewRow2.value.set(m[2], m[6], m[10], m[14]);\n this.activeCount.value = activeCount;\n if (!this.exactDepth) {\n this.viewCenter.copy(bounds.center).applyMatrix4(modelView);\n const viewRadius = viewDepthRadius(modelView, bounds.radius);\n const minimum = this.viewCenter.z - viewRadius;\n const maximum = this.viewCenter.z + viewRadius;\n this.depthMin.value = minimum;\n this.depthScale.value = RADIX_KEY_MAX / (maximum - minimum || 1);\n }\n this.stages[0]!.count = activeCount;\n this.stages[this.stages.length - 1]!.count = activeCount;\n this.renderer.compute(this.stages);\n // Key/value ping-pong, histogram, scan sums and masks are all written and\n // read entirely on the GPU - at 4 B per splat of capacity each, their JS\n // mirrors are ~16 B/splat of pure waste. Deliberately *not*\n // `sourceIndex`/`splatIndex`: those belong to the mesh and are rewritten\n // from the CPU every frame. Same ownership line as `releaseRendererAttributes`.\n if (!this.mirrors.settled) this.mirrors.release(this.renderer);\n return true;\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n for (const stage of this.stages) stage.dispose();\n releaseRendererAttributes(this.renderer, this.workingAttributes);\n }\n}\n"],"names":["RADIX_KEY_BITS","RADIX_EXACT_KEY_BITS","RADIX_BITS_PER_PASS","RADIX_KEY_MAX","radixPassCount","keyBits","WORKGROUP_SIZE","ELEMENTS_PER_THREAD","ELEMENTS_PER_WORKGROUP","DIGIT_COUNT","MASK_WORDS_PER_DIGIT","MASK_WORDS_PER_GROUP","SCAN_BLOCK_SIZE","RadixSorter","options","__publicField","uniform","THREE","capacity","centersTexture","dataTextureWidth","centersBuffer","exactDepth","passCount","groupCount","histogramLength","scanBlockCount","keysAAttribute","keysBAttribute","valuesAAttribute","valuesBAttribute","histogramAttribute","scanSumsAttribute","masksAttribute","StorageMirrorReleaser","keysA","storage","keysB","valuesA","valuesB","source","order","workCenters","histogram","scanSums","masks","buildKeys","Fn","If","float","instanceIndex","poolIndex","texel","ivec2","int","center","textureLoad","depth","bits","floatBitsToUint","mask","uint","pass","inputKeys","outputKeys","inputValues","outputValues","bit","clearHistogram","atomicStore","buildHistogram","base","workgroupId","Loop","i","index","invocationLocalIndex","digit","atomicAdd","scanBlocks","start","running","value","atomicLoad","scanBlockSums","addBlockOffsets","block","digitOffsets","workgroupArray","rankedScatter","thread","group","maskBase","storageBarrier","workgroupBarrier","valid","key","word","bitInWord","maskIndex","atomicOr","digitBase","localRank","wordIndex","countOneBits","precedingMask","target","total","writeOrder","modelView","activeCount","bounds","m","viewRadius","viewDepthRadius","minimum","maximum","stage","releaseRendererAttributes"],"mappings":"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"}