gaussian-splat-lite 1.0.1 → 1.0.2
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/CHANGELOG.md +10 -1
- package/dist/gaussian-splat-lite.cjs +65 -75
- package/dist/gaussian-splat-lite.cjs.map +1 -1
- package/dist/gaussian-splat-lite.min.cjs +20 -20
- package/dist/gaussian-splat-lite.min.cjs.map +1 -1
- package/dist/gaussian-splat-lite.module.js +65 -75
- package/dist/gaussian-splat-lite.module.js.map +1 -1
- package/dist/gaussian-splat-lite.module.min.js +433 -441
- package/dist/gaussian-splat-lite.module.min.js.map +1 -1
- package/dist/types/rendering/webgpu/ProjectedSplats.d.cts +4 -2
- package/dist/types/rendering/webgpu/ProjectedSplats.d.ts +4 -2
- package/package.json +1 -1
|
@@ -4913,11 +4913,8 @@ const ELEMENTS_PER_THREAD = 8;
|
|
|
4913
4913
|
const ELEMENTS_PER_WORKGROUP = WORKGROUP_SIZE$1 * ELEMENTS_PER_THREAD;
|
|
4914
4914
|
const PREFIX_ITEMS_PER_WORKGROUP = WORKGROUP_SIZE$1 * 2;
|
|
4915
4915
|
const PREFIX_LEVELS = 3;
|
|
4916
|
-
function storage(buffer2,
|
|
4917
|
-
|
|
4918
|
-
const node = N$2.storage(getBuffer(), type).onObjectUpdate(getBuffer);
|
|
4919
|
-
node.name = name;
|
|
4920
|
-
return readOnly ? node.toReadOnly() : node;
|
|
4916
|
+
function storage(buffer2, name) {
|
|
4917
|
+
return N$2.storage(buffer2.value, "uint").setName(name).onObjectUpdate(() => buffer2.value);
|
|
4921
4918
|
}
|
|
4922
4919
|
function mutableUniform(value, type) {
|
|
4923
4920
|
const holder = { value };
|
|
@@ -4942,8 +4939,8 @@ function makeHistogramTask({
|
|
|
4942
4939
|
bitOffset,
|
|
4943
4940
|
workgroupCount
|
|
4944
4941
|
}) {
|
|
4945
|
-
const inputKeys = storage(input, "
|
|
4946
|
-
const sums = storage(blockSums, "
|
|
4942
|
+
const inputKeys = storage(input, "gslRadixInputKeys").toReadOnly();
|
|
4943
|
+
const sums = storage(blockSums, "gslRadixBlockSums");
|
|
4947
4944
|
const bit = N$2.uint(bitOffset);
|
|
4948
4945
|
const histogram = N$2.workgroupArray("uint", RADIX_BUCKETS).toAtomic().setName("gslRadixHistogram");
|
|
4949
4946
|
return N$2.Fn(() => {
|
|
@@ -4976,8 +4973,8 @@ function makeHistogramTask({
|
|
|
4976
4973
|
})().compute([1, 1, 1], [WORKGROUP_SIZE$1]).setName("Splat radix histogram");
|
|
4977
4974
|
}
|
|
4978
4975
|
function makePrefixScanTask(itemsBuffer, blockSumsBuffer, elementCount) {
|
|
4979
|
-
const items = storage(itemsBuffer, "
|
|
4980
|
-
const blockSums = storage(blockSumsBuffer, "
|
|
4976
|
+
const items = storage(itemsBuffer, "gslPrefixItems");
|
|
4977
|
+
const blockSums = storage(blockSumsBuffer, "gslPrefixBlockSums");
|
|
4981
4978
|
const temp = N$2.workgroupArray("uint", PREFIX_ITEMS_PER_WORKGROUP).setName(
|
|
4982
4979
|
"gslPrefixTemp"
|
|
4983
4980
|
);
|
|
@@ -5049,13 +5046,8 @@ function makePrefixScanTask(itemsBuffer, blockSumsBuffer, elementCount) {
|
|
|
5049
5046
|
return compute;
|
|
5050
5047
|
}
|
|
5051
5048
|
function makePrefixAddTask(itemsBuffer, blockSumsBuffer, elementCount) {
|
|
5052
|
-
const items = storage(itemsBuffer, "
|
|
5053
|
-
const blockSums = storage(
|
|
5054
|
-
blockSumsBuffer,
|
|
5055
|
-
"uint",
|
|
5056
|
-
"gslPrefixBlockSums",
|
|
5057
|
-
true
|
|
5058
|
-
);
|
|
5049
|
+
const items = storage(itemsBuffer, "gslPrefixItems");
|
|
5050
|
+
const blockSums = storage(blockSumsBuffer, "gslPrefixBlockSums").toReadOnly();
|
|
5059
5051
|
const compute = N$2.Fn(() => {
|
|
5060
5052
|
const workgroup = workgroupIndex();
|
|
5061
5053
|
const first = workgroup.mul(PREFIX_ITEMS_PER_WORKGROUP).add(N$2.invocationLocalIndex.mul(2));
|
|
@@ -5085,23 +5077,15 @@ function makeReorderTask({
|
|
|
5085
5077
|
}) {
|
|
5086
5078
|
const inputKeys = storage(
|
|
5087
5079
|
inputKeysAttribute,
|
|
5088
|
-
"
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
);
|
|
5092
|
-
const outputKeys = lastPass ? null : storage(outputKeysAttribute, "uint", "gslRadixOutputKeys");
|
|
5080
|
+
"gslRadixInputKeys"
|
|
5081
|
+
).toReadOnly();
|
|
5082
|
+
const outputKeys = lastPass ? null : storage(outputKeysAttribute, "gslRadixOutputKeys");
|
|
5093
5083
|
const inputValues = storage(
|
|
5094
5084
|
inputValuesAttribute,
|
|
5095
|
-
"
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
);
|
|
5099
|
-
const outputValues = storage(
|
|
5100
|
-
outputValuesAttribute,
|
|
5101
|
-
"uint",
|
|
5102
|
-
"gslRadixOutputValues"
|
|
5103
|
-
);
|
|
5104
|
-
const prefix = storage(prefixAttribute, "uint", "gslRadixPrefix", true);
|
|
5085
|
+
"gslRadixInputValues"
|
|
5086
|
+
).toReadOnly();
|
|
5087
|
+
const outputValues = storage(outputValuesAttribute, "gslRadixOutputValues");
|
|
5088
|
+
const prefix = storage(prefixAttribute, "gslRadixPrefix").toReadOnly();
|
|
5105
5089
|
const bitOffsetNode = N$2.uint(bitOffset);
|
|
5106
5090
|
const digitMasks = N$2.workgroupArray("uint", RADIX_BUCKETS * 8).toAtomic().setName("gslRadixDigitMasks");
|
|
5107
5091
|
const digitOffsets = N$2.workgroupArray("uint", RADIX_BUCKETS).setName(
|
|
@@ -5224,7 +5208,7 @@ class WebGPURadixSort {
|
|
|
5224
5208
|
this.values = [makeBufferRef(safeCapacity), makeBufferRef(safeCapacity)];
|
|
5225
5209
|
const histogramCount = RADIX_BUCKETS * this.paddedWorkgroups(safeCapacity, ELEMENTS_PER_WORKGROUP);
|
|
5226
5210
|
this.blockSums = makeBufferRef(histogramCount);
|
|
5227
|
-
const counts = storage(this.counts, "
|
|
5211
|
+
const counts = storage(this.counts, "gslRadixCounts").toReadOnly();
|
|
5228
5212
|
this.createPrefixLevels(histogramCount, counts);
|
|
5229
5213
|
const setup = this.makeSetupTask(options.count);
|
|
5230
5214
|
const prefixNodes = this.prefixLevels.map((_, lastLevel) => {
|
|
@@ -5291,13 +5275,11 @@ class WebGPURadixSort {
|
|
|
5291
5275
|
return Math.max(1, width * Math.ceil(groups / this.maxWorkgroups));
|
|
5292
5276
|
}
|
|
5293
5277
|
makeSetupTask(gpuCount) {
|
|
5294
|
-
const counts = storage(this.counts, "
|
|
5278
|
+
const counts = storage(this.counts, "gslRadixCounts");
|
|
5295
5279
|
const dispatchBuffers = [
|
|
5296
5280
|
this.sortDispatch,
|
|
5297
5281
|
...this.prefixLevels.map((level) => level.dispatch)
|
|
5298
|
-
].map(
|
|
5299
|
-
(value, index2) => storage({ value }, "uint", `gslRadixDispatch${index2}`)
|
|
5300
|
-
);
|
|
5282
|
+
].map((value, index2) => storage({ value }, `gslRadixDispatch${index2}`));
|
|
5301
5283
|
const maxWorkgroups = N$2.uint(this.maxWorkgroups);
|
|
5302
5284
|
return N$2.Fn(() => {
|
|
5303
5285
|
const count = N$2.min(
|
|
@@ -5409,29 +5391,31 @@ class WebGPURadixSort {
|
|
|
5409
5391
|
const N$1 = TSL;
|
|
5410
5392
|
const WORKGROUP_SIZE = 256;
|
|
5411
5393
|
const PROJECT_SLOTS = 8;
|
|
5412
|
-
function buffer(
|
|
5413
|
-
return { value: new StorageBufferAttribute(new Uint32Array(
|
|
5394
|
+
function buffer(name) {
|
|
5395
|
+
return { value: new StorageBufferAttribute(new Uint32Array(1), 1), name };
|
|
5414
5396
|
}
|
|
5415
|
-
function bindBuffer(ref
|
|
5416
|
-
|
|
5417
|
-
return readOnly ? node.toReadOnly() : node;
|
|
5397
|
+
function bindBuffer(ref) {
|
|
5398
|
+
return N$1.storage(ref.value, "uint").setName(ref.name).onObjectUpdate(() => ref.value);
|
|
5418
5399
|
}
|
|
5419
5400
|
class ProjectedSplats {
|
|
5420
5401
|
constructor(renderer, uniforms) {
|
|
5421
5402
|
this.renderer = renderer;
|
|
5422
5403
|
this.uniforms = uniforms;
|
|
5423
|
-
this.indirect = new IndirectStorageBufferAttribute(
|
|
5424
|
-
|
|
5404
|
+
this.indirect = new IndirectStorageBufferAttribute(
|
|
5405
|
+
new Uint32Array([WEBGPU_SPLATS_PER_INSTANCE * 6, 0, 0, 0, 0]),
|
|
5406
|
+
1
|
|
5407
|
+
);
|
|
5425
5408
|
this.error = null;
|
|
5426
5409
|
this.cache = new ProjectionCache();
|
|
5427
5410
|
this.visibleCount = new StorageBufferAttribute(
|
|
5428
5411
|
new Uint32Array(1),
|
|
5429
5412
|
1
|
|
5430
5413
|
);
|
|
5431
|
-
this.keys = buffer();
|
|
5432
|
-
this.seeds = buffer();
|
|
5433
|
-
this.counts = buffer();
|
|
5414
|
+
this.keys = buffer("gslProjectionKeys");
|
|
5415
|
+
this.seeds = buffer("gslProjectionSeeds");
|
|
5416
|
+
this.counts = buffer("gslProjectionCounts");
|
|
5434
5417
|
this.slots = [];
|
|
5418
|
+
this.compiledSlots = 0;
|
|
5435
5419
|
this.matrix = new THREE.Matrix4();
|
|
5436
5420
|
this.translation = new THREE.Matrix4();
|
|
5437
5421
|
this.scale = new THREE.Vector3();
|
|
@@ -5461,8 +5445,8 @@ class ProjectedSplats {
|
|
|
5461
5445
|
const viewBase = uniformBinding(this.state, "viewBase", "uint");
|
|
5462
5446
|
const multiView = uniformBinding(this.state, "multiView", "bool");
|
|
5463
5447
|
const stochastic = uniformBinding(uniforms, "stochastic", "bool");
|
|
5464
|
-
const count = N$1.storage(this.visibleCount, "uint").toReadOnly().element(0);
|
|
5465
|
-
const seeds = bindBuffer(this.seeds
|
|
5448
|
+
const count = N$1.storage(this.visibleCount, "uint").setName("gslVisibleCount").toReadOnly().element(0);
|
|
5449
|
+
const seeds = bindBuffer(this.seeds).toReadOnly();
|
|
5466
5450
|
this.sorter = new WebGPURadixSort(1, this.keys, {
|
|
5467
5451
|
count,
|
|
5468
5452
|
storeOrder: (index2, value) => {
|
|
@@ -5479,15 +5463,8 @@ class ProjectedSplats {
|
|
|
5479
5463
|
this.limits.maxBufferSize
|
|
5480
5464
|
)
|
|
5481
5465
|
});
|
|
5482
|
-
const
|
|
5483
|
-
|
|
5484
|
-
draw.element(0).assign(WEBGPU_SPLATS_PER_INSTANCE * 6);
|
|
5485
|
-
draw.element(1).assign(0);
|
|
5486
|
-
draw.element(2).assign(0);
|
|
5487
|
-
draw.element(3).assign(0);
|
|
5488
|
-
draw.element(4).assign(0);
|
|
5489
|
-
})().compute(1).setName("Splat reset draw");
|
|
5490
|
-
const counter = N$1.storage(this.visibleCount, "uint").toAtomic();
|
|
5466
|
+
const drawCount = N$1.storage(this.indirect, "uint").setName("gslDrawIndirect").element(1);
|
|
5467
|
+
const counter = N$1.storage(this.visibleCount, "uint").setName("gslVisibleCount").toAtomic();
|
|
5491
5468
|
this.resetCount = N$1.Fn(() => {
|
|
5492
5469
|
N$1.atomicStore(counter.element(0), N$1.uint(0));
|
|
5493
5470
|
})().compute(1, [1]).setName("Splat reset visible count");
|
|
@@ -5498,7 +5475,9 @@ class ProjectedSplats {
|
|
|
5498
5475
|
N$1.If(index2.equal(0), () => {
|
|
5499
5476
|
counts.element(viewIndex).assign(count);
|
|
5500
5477
|
const instances = count.add(WEBGPU_SPLATS_PER_INSTANCE - 1).div(N$1.uint(WEBGPU_SPLATS_PER_INSTANCE));
|
|
5501
|
-
|
|
5478
|
+
drawCount.assign(
|
|
5479
|
+
N$1.select(viewIndex.equal(0), instances, drawCount.max(instances))
|
|
5480
|
+
);
|
|
5502
5481
|
});
|
|
5503
5482
|
N$1.If(multiView.and(stochastic).and(index2.lessThan(count)), () => {
|
|
5504
5483
|
this.cache.storeOrder(
|
|
@@ -5509,17 +5488,30 @@ class ProjectedSplats {
|
|
|
5509
5488
|
})().compute(1, [WORKGROUP_SIZE]).setName("Splat visible draw arguments");
|
|
5510
5489
|
for (let i = 0; i < PROJECT_SLOTS; i++) this.slots.push(this.createSlot());
|
|
5511
5490
|
this.ready = computeRenderer.compileComputeAsync([
|
|
5512
|
-
this.resetDraw,
|
|
5513
5491
|
this.resetCount,
|
|
5514
5492
|
this.finish,
|
|
5515
|
-
...this.
|
|
5516
|
-
|
|
5517
|
-
]).
|
|
5493
|
+
...this.sorter.nodes,
|
|
5494
|
+
this.slots[0].node
|
|
5495
|
+
]).then(() => {
|
|
5496
|
+
this.compiledSlots = 1;
|
|
5497
|
+
}).catch((error) => {
|
|
5518
5498
|
this.error = error;
|
|
5519
|
-
}).finally(() => {
|
|
5520
|
-
this.pending = false;
|
|
5521
|
-
if (this.disposed) this.disposeResources();
|
|
5522
5499
|
});
|
|
5500
|
+
this.compilation = this.ready.then(() => this.compileRemainingSlots());
|
|
5501
|
+
}
|
|
5502
|
+
async compileRemainingSlots() {
|
|
5503
|
+
if (this.disposed || this.compiledSlots === 0) return;
|
|
5504
|
+
try {
|
|
5505
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
5506
|
+
while (!this.disposed && this.compiledSlots < this.slots.length) {
|
|
5507
|
+
await this.renderer.compileComputeAsync([
|
|
5508
|
+
this.slots[this.compiledSlots].node
|
|
5509
|
+
]);
|
|
5510
|
+
this.compiledSlots++;
|
|
5511
|
+
}
|
|
5512
|
+
} catch (error) {
|
|
5513
|
+
this.error = error;
|
|
5514
|
+
}
|
|
5523
5515
|
}
|
|
5524
5516
|
createSlot() {
|
|
5525
5517
|
const uniforms = { ...this.state, ...makeGenerateUniforms() };
|
|
@@ -5543,7 +5535,7 @@ class ProjectedSplats {
|
|
|
5543
5535
|
const pixelScale = u("renderSize", "vec2").mul(u("focalAdjustment", "float")).mul(0.5);
|
|
5544
5536
|
const keys = bindBuffer(this.keys);
|
|
5545
5537
|
const seeds = bindBuffer(this.seeds);
|
|
5546
|
-
const counter = N$1.storage(this.visibleCount, "uint").toAtomic();
|
|
5538
|
+
const counter = N$1.storage(this.visibleCount, "uint").setName("gslVisibleCount").toAtomic();
|
|
5547
5539
|
const node = N$1.Fn(() => {
|
|
5548
5540
|
const index2 = N$1.uint(N$1.instanceIndex);
|
|
5549
5541
|
const generated = generate.prepare(index2);
|
|
@@ -5596,7 +5588,7 @@ class ProjectedSplats {
|
|
|
5596
5588
|
const stride = uniformBinding(this.state, "viewStride", "uint");
|
|
5597
5589
|
const base = eye.mul(stride).toVar();
|
|
5598
5590
|
const i = N$1.uint(N$1.instanceIndex).mul(WEBGPU_SPLATS_PER_INSTANCE).add(N$1.uint(N$1.positionGeometry.z));
|
|
5599
|
-
const counts = bindBuffer(this.counts
|
|
5591
|
+
const counts = bindBuffer(this.counts).toReadOnly();
|
|
5600
5592
|
const clipPosition = N$1.vec4(0, 0, 2, 1).toVar();
|
|
5601
5593
|
const rgba = N$1.vec4(0).toVar();
|
|
5602
5594
|
const splatUv = N$1.vec2(0).toVar();
|
|
@@ -5612,7 +5604,7 @@ class ProjectedSplats {
|
|
|
5612
5604
|
const cacheIndex = i.toVar();
|
|
5613
5605
|
const assignSeed = () => {
|
|
5614
5606
|
stochasticSeed.assign(
|
|
5615
|
-
multiView ? this.cache.readOrder(base.add(i)).y : bindBuffer(this.seeds
|
|
5607
|
+
multiView ? this.cache.readOrder(base.add(i)).y : bindBuffer(this.seeds).toReadOnly().element(i)
|
|
5616
5608
|
);
|
|
5617
5609
|
};
|
|
5618
5610
|
if (depthOnly) {
|
|
@@ -5691,7 +5683,7 @@ class ProjectedSplats {
|
|
|
5691
5683
|
}
|
|
5692
5684
|
render(accumulator, camera, geometry, radial, shrink = false) {
|
|
5693
5685
|
if (this.error) throw this.error;
|
|
5694
|
-
if (this.
|
|
5686
|
+
if (this.compiledSlots === 0 || this.disposed) {
|
|
5695
5687
|
geometry.instanceCount = 0;
|
|
5696
5688
|
return;
|
|
5697
5689
|
}
|
|
@@ -5725,12 +5717,11 @@ class ProjectedSplats {
|
|
|
5725
5717
|
this.scale
|
|
5726
5718
|
);
|
|
5727
5719
|
this.state.renderToViewScale.value = (this.scale.x + this.scale.y + this.scale.z) / 3;
|
|
5728
|
-
const pending =
|
|
5729
|
-
pending.push(this.resetCount);
|
|
5720
|
+
const pending = [this.resetCount];
|
|
5730
5721
|
let slotCount = 0;
|
|
5731
5722
|
for (const { node, count } of accumulator.mapping) {
|
|
5732
5723
|
if (!view.layers.test(node.layers)) continue;
|
|
5733
|
-
if (slotCount ===
|
|
5724
|
+
if (slotCount === this.compiledSlots) {
|
|
5734
5725
|
this.renderer.compute(pending);
|
|
5735
5726
|
pending.length = 0;
|
|
5736
5727
|
slotCount = 0;
|
|
@@ -5751,12 +5742,11 @@ class ProjectedSplats {
|
|
|
5751
5742
|
dispose() {
|
|
5752
5743
|
if (this.disposed) return;
|
|
5753
5744
|
this.disposed = true;
|
|
5754
|
-
|
|
5745
|
+
void this.compilation.then(() => this.disposeResources());
|
|
5755
5746
|
}
|
|
5756
5747
|
disposeResources() {
|
|
5757
5748
|
for (const slot of this.slots) slot.node.dispose();
|
|
5758
|
-
for (const node of [this.
|
|
5759
|
-
node.dispose();
|
|
5749
|
+
for (const node of [this.resetCount, this.finish]) node.dispose();
|
|
5760
5750
|
this.sorter.dispose();
|
|
5761
5751
|
this.cache.dispose();
|
|
5762
5752
|
this.visibleCount.dispose();
|