@driftengine/splats 3.63.0 → 4.0.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.
- package/NOTICE +20 -0
- package/dist/splatMatrix.d.ts +13 -1
- package/dist/splatMatrix.js +17 -1
- package/dist/splatPass.js +10 -1
- package/dist/splatSortWorker.js +4 -1
- package/package.json +2 -2
- package/src/splatMatrix.ts +25 -1
- package/src/splatPass.ts +10 -1
- package/src/splatSortWorker.ts +2 -0
package/NOTICE
CHANGED
|
@@ -7,3 +7,23 @@ This product includes software developed at Drift Technologies
|
|
|
7
7
|
Licensed under the Apache License, Version 2.0. Section 4(d) of that licence
|
|
8
8
|
requires this NOTICE to be reproduced in any derivative work you distribute,
|
|
9
9
|
in the source, the documentation, or a display generated by the work.
|
|
10
|
+
|
|
11
|
+
Models run by DriftCapture
|
|
12
|
+
--------------------------
|
|
13
|
+
DriftCapture runs the models below. Their weights are not in this repository
|
|
14
|
+
and are not distributed with it: tools/capture-weights/ fetches each at the
|
|
15
|
+
revision its manifest pins, verifies it, and converts it, and a game that
|
|
16
|
+
ships one ships it under that model's own licence. Each model's definition in
|
|
17
|
+
this engine is written from its project's published code.
|
|
18
|
+
|
|
19
|
+
- Depth Anything 3 Small and Depth Anything 3 Base. Apache License 2.0.
|
|
20
|
+
Copyright (c) 2025 ByteDance Ltd. and/or its affiliates.
|
|
21
|
+
- Depth Anything V2 Small. Apache License 2.0. The University of Hong Kong
|
|
22
|
+
and TikTok; converted to the Transformers layout by The HuggingFace Team.
|
|
23
|
+
- MobileSAM. Apache License 2.0. Its image encoder is TinyViT, Copyright (c)
|
|
24
|
+
2022 Microsoft; its prompt encoder and mask decoder are Segment Anything's,
|
|
25
|
+
Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
26
|
+
- SAM 2.1 tiny. Apache License 2.0. Copyright (c) Meta Platforms, Inc. and
|
|
27
|
+
affiliates.
|
|
28
|
+
- OWLv2 base patch16. Apache License 2.0. Copyright 2023 Google AI and The
|
|
29
|
+
HuggingFace Team.
|
package/dist/splatMatrix.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** The
|
|
1
|
+
/** The matrix operations this package needs, written once so no two callers disagree. */
|
|
2
2
|
/**
|
|
3
3
|
* `out = a * b`, column-major, sixteen multiply-adds and no dependency.
|
|
4
4
|
*
|
|
@@ -27,3 +27,15 @@ export declare function multiplyMat4(out: Float32Array, a: ArrayLike<number>, b:
|
|
|
27
27
|
* once per splat times six.
|
|
28
28
|
*/
|
|
29
29
|
export declare function cameraInCaptureSpace(out: Float32Array, view: ArrayLike<number>, model: ArrayLike<number>): void;
|
|
30
|
+
/**
|
|
31
|
+
* The projection a frame draws a capture with: the caller's, moved by the frame's jitter, then
|
|
32
|
+
* corrected for the backend. `scratch` holds sixteen floats and is overwritten.
|
|
33
|
+
*
|
|
34
|
+
* **In that order, because the jitter is stated in the camera's own convention** — see
|
|
35
|
+
* `PrepareContext.jitter`. A reconstructed frame un-jitters every sample it takes, so a capture
|
|
36
|
+
* drawn without the offset is placed up to half a render pixel from where the resolve looks for it,
|
|
37
|
+
* differently each frame; and the correction negates y, so the same offset applied after it lands
|
|
38
|
+
* on the other side of the pixel. A frame that is not reconstructed hands a zero jitter, and the
|
|
39
|
+
* result is the corrected projection it always was.
|
|
40
|
+
*/
|
|
41
|
+
export declare function projectionForFrame(out: Float32Array, correction: ArrayLike<number>, projection: ArrayLike<number>, jitter: ArrayLike<number>, scratch: Float32Array): void;
|
package/dist/splatMatrix.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** The
|
|
1
|
+
/** The matrix operations this package needs, written once so no two callers disagree. */
|
|
2
|
+
import { jitterClip } from '@driftengine/core';
|
|
2
3
|
/**
|
|
3
4
|
* `out = a * b`, column-major, sixteen multiply-adds and no dependency.
|
|
4
5
|
*
|
|
@@ -66,3 +67,18 @@ export function cameraInCaptureSpace(out, view, model) {
|
|
|
66
67
|
}
|
|
67
68
|
/** Scratch for the product above, so a frame allocates nothing. */
|
|
68
69
|
const PRODUCT = new Float32Array(16);
|
|
70
|
+
/**
|
|
71
|
+
* The projection a frame draws a capture with: the caller's, moved by the frame's jitter, then
|
|
72
|
+
* corrected for the backend. `scratch` holds sixteen floats and is overwritten.
|
|
73
|
+
*
|
|
74
|
+
* **In that order, because the jitter is stated in the camera's own convention** — see
|
|
75
|
+
* `PrepareContext.jitter`. A reconstructed frame un-jitters every sample it takes, so a capture
|
|
76
|
+
* drawn without the offset is placed up to half a render pixel from where the resolve looks for it,
|
|
77
|
+
* differently each frame; and the correction negates y, so the same offset applied after it lands
|
|
78
|
+
* on the other side of the pixel. A frame that is not reconstructed hands a zero jitter, and the
|
|
79
|
+
* result is the corrected projection it always was.
|
|
80
|
+
*/
|
|
81
|
+
export function projectionForFrame(out, correction, projection, jitter, scratch) {
|
|
82
|
+
jitterClip(scratch, projection, jitter);
|
|
83
|
+
multiplyMat4(out, correction, scratch);
|
|
84
|
+
}
|
package/dist/splatPass.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** A splat capture as a pass a consumer registers, drawn by whichever backend it is handed. */
|
|
2
2
|
import { SPLAT_BINDINGS } from './shaders/generated/splat.wgsl.js';
|
|
3
3
|
import { SPLAT_STRIDE, splatRows, splatTexels } from './splatLayout.js';
|
|
4
|
-
import { cameraInCaptureSpace, multiplyMat4 } from './splatMatrix.js';
|
|
4
|
+
import { cameraInCaptureSpace, multiplyMat4, projectionForFrame } from './splatMatrix.js';
|
|
5
5
|
import { splatBoundsVisible } from './splatCull.js';
|
|
6
6
|
import { createWebgl2Splats, disposeWebgl2Splats, drawWebgl2Splats, uploadWebgl2Order, uploadWebgl2SplatRange, } from './splatGl.js';
|
|
7
7
|
import { createGpuSplats, disposeGpuSplats, uploadGpuOrder, uploadGpuSplatRange, } from './splatGpu.js';
|
|
@@ -31,6 +31,12 @@ export function createSplatPass(splats, label = 'splats') {
|
|
|
31
31
|
const view = new Float32Array(16);
|
|
32
32
|
/** The caller's projection, pre-multiplied by the backend's clip correction. */
|
|
33
33
|
const projection = new Float32Array(16);
|
|
34
|
+
/**
|
|
35
|
+
* The caller's projection as given, kept so a WebGPU frame can move it by the frame's jitter
|
|
36
|
+
* before correcting it. See `projectionForFrame`.
|
|
37
|
+
*/
|
|
38
|
+
const callerProjection = new Float32Array(IDENTITY);
|
|
39
|
+
const jitterScratch = new Float32Array(16);
|
|
34
40
|
/**
|
|
35
41
|
* Where the camera is in the capture's own space, which is where the harmonics were trained.
|
|
36
42
|
*
|
|
@@ -81,6 +87,7 @@ export function createSplatPass(splats, label = 'splats') {
|
|
|
81
87
|
},
|
|
82
88
|
setView(next) {
|
|
83
89
|
view.set(next.view);
|
|
90
|
+
callerProjection.set(next.projection);
|
|
84
91
|
multiplyMat4(projection, clipCorrection, next.projection);
|
|
85
92
|
viewportX = next.widthPx;
|
|
86
93
|
viewportY = next.heightPx;
|
|
@@ -175,6 +182,8 @@ export function createSplatPass(splats, label = 'splats') {
|
|
|
175
182
|
uploadGpuOrder(device, gpu, pendingOrder, paddedOrder);
|
|
176
183
|
pendingOrder = null;
|
|
177
184
|
}
|
|
185
|
+
/* The frame's jitter, which is zero unless the frame is reconstructed. */
|
|
186
|
+
projectionForFrame(projection, clipCorrection, callerProjection, ctx.jitter, jitterScratch);
|
|
178
187
|
writeVertexUniforms(gpu);
|
|
179
188
|
device.queue.writeBuffer(gpu.vertexUniforms, 0, gpu.vertexScratch);
|
|
180
189
|
gpu.fragmentInts[FRAG.fields.uOutputTransform.offset / 4] = ctx.outputTransform;
|
package/dist/splatSortWorker.js
CHANGED
|
@@ -77,12 +77,15 @@ export function createSplatSortWorker(sortSource) {
|
|
|
77
77
|
return sortOnMainThread;
|
|
78
78
|
};
|
|
79
79
|
try {
|
|
80
|
-
if (
|
|
80
|
+
if (
|
|
81
|
+
// platform: feature probe — the fallback sorts on this thread and says so
|
|
82
|
+
typeof Worker === 'undefined' ||
|
|
81
83
|
typeof Blob === 'undefined' ||
|
|
82
84
|
typeof URL === 'undefined') {
|
|
83
85
|
return fallback('this runtime has no Worker');
|
|
84
86
|
}
|
|
85
87
|
const url = URL.createObjectURL(new Blob([workerSource(sortSource)], { type: 'text/javascript' }));
|
|
88
|
+
// platform: browser default — a blob worker, guarded by the probe above
|
|
86
89
|
worker = new Worker(url);
|
|
87
90
|
/* The blob is referenced by the live worker; the URL is only the handle. */
|
|
88
91
|
URL.revokeObjectURL(url);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@driftengine/splats",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Gaussian splat captures: readers, an off-frame sort, and a pass that composes into the scene",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@driftengine/core": "
|
|
30
|
+
"@driftengine/core": "4.0.0"
|
|
31
31
|
},
|
|
32
32
|
"author": "Drift Technologies",
|
|
33
33
|
"repository": {
|
package/src/splatMatrix.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
/** The
|
|
1
|
+
/** The matrix operations this package needs, written once so no two callers disagree. */
|
|
2
|
+
|
|
3
|
+
import { jitterClip } from '@driftengine/core';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* `out = a * b`, column-major, sixteen multiply-adds and no dependency.
|
|
@@ -79,3 +81,25 @@ export function cameraInCaptureSpace(
|
|
|
79
81
|
|
|
80
82
|
/** Scratch for the product above, so a frame allocates nothing. */
|
|
81
83
|
const PRODUCT = new Float32Array(16);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The projection a frame draws a capture with: the caller's, moved by the frame's jitter, then
|
|
87
|
+
* corrected for the backend. `scratch` holds sixteen floats and is overwritten.
|
|
88
|
+
*
|
|
89
|
+
* **In that order, because the jitter is stated in the camera's own convention** — see
|
|
90
|
+
* `PrepareContext.jitter`. A reconstructed frame un-jitters every sample it takes, so a capture
|
|
91
|
+
* drawn without the offset is placed up to half a render pixel from where the resolve looks for it,
|
|
92
|
+
* differently each frame; and the correction negates y, so the same offset applied after it lands
|
|
93
|
+
* on the other side of the pixel. A frame that is not reconstructed hands a zero jitter, and the
|
|
94
|
+
* result is the corrected projection it always was.
|
|
95
|
+
*/
|
|
96
|
+
export function projectionForFrame(
|
|
97
|
+
out: Float32Array,
|
|
98
|
+
correction: ArrayLike<number>,
|
|
99
|
+
projection: ArrayLike<number>,
|
|
100
|
+
jitter: ArrayLike<number>,
|
|
101
|
+
scratch: Float32Array,
|
|
102
|
+
): void {
|
|
103
|
+
jitterClip(scratch, projection, jitter);
|
|
104
|
+
multiplyMat4(out, correction, scratch);
|
|
105
|
+
}
|
package/src/splatPass.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { SPLAT_BINDINGS } from './shaders/generated/splat.wgsl.ts';
|
|
4
4
|
import { SPLAT_STRIDE, splatRows, splatTexels } from './splatLayout.ts';
|
|
5
|
-
import { cameraInCaptureSpace, multiplyMat4 } from './splatMatrix.ts';
|
|
5
|
+
import { cameraInCaptureSpace, multiplyMat4, projectionForFrame } from './splatMatrix.ts';
|
|
6
6
|
import { splatBoundsVisible } from './splatCull.ts';
|
|
7
7
|
import {
|
|
8
8
|
createWebgl2Splats,
|
|
@@ -125,6 +125,12 @@ export function createSplatPass(splats: SplatData, label = 'splats'): SplatPass
|
|
|
125
125
|
const view = new Float32Array(16);
|
|
126
126
|
/** The caller's projection, pre-multiplied by the backend's clip correction. */
|
|
127
127
|
const projection = new Float32Array(16);
|
|
128
|
+
/**
|
|
129
|
+
* The caller's projection as given, kept so a WebGPU frame can move it by the frame's jitter
|
|
130
|
+
* before correcting it. See `projectionForFrame`.
|
|
131
|
+
*/
|
|
132
|
+
const callerProjection = new Float32Array(IDENTITY);
|
|
133
|
+
const jitterScratch = new Float32Array(16);
|
|
128
134
|
/**
|
|
129
135
|
* Where the camera is in the capture's own space, which is where the harmonics were trained.
|
|
130
136
|
*
|
|
@@ -186,6 +192,7 @@ export function createSplatPass(splats: SplatData, label = 'splats'): SplatPass
|
|
|
186
192
|
|
|
187
193
|
setView(next: SplatView): void {
|
|
188
194
|
view.set(next.view);
|
|
195
|
+
callerProjection.set(next.projection);
|
|
189
196
|
multiplyMat4(projection, clipCorrection, next.projection);
|
|
190
197
|
viewportX = next.widthPx;
|
|
191
198
|
viewportY = next.heightPx;
|
|
@@ -291,6 +298,8 @@ export function createSplatPass(splats: SplatData, label = 'splats'): SplatPass
|
|
|
291
298
|
uploadGpuOrder(device, gpu, pendingOrder, paddedOrder);
|
|
292
299
|
pendingOrder = null;
|
|
293
300
|
}
|
|
301
|
+
/* The frame's jitter, which is zero unless the frame is reconstructed. */
|
|
302
|
+
projectionForFrame(projection, clipCorrection, callerProjection, ctx.jitter, jitterScratch);
|
|
294
303
|
writeVertexUniforms(gpu);
|
|
295
304
|
device.queue.writeBuffer(gpu.vertexUniforms, 0, gpu.vertexScratch);
|
|
296
305
|
gpu.fragmentInts[FRAG.fields.uOutputTransform.offset / 4] = ctx.outputTransform;
|
package/src/splatSortWorker.ts
CHANGED
|
@@ -86,6 +86,7 @@ export function createSplatSortWorker(sortSource: string): SplatSortFn {
|
|
|
86
86
|
|
|
87
87
|
try {
|
|
88
88
|
if (
|
|
89
|
+
// platform: feature probe — the fallback sorts on this thread and says so
|
|
89
90
|
typeof Worker === 'undefined' ||
|
|
90
91
|
typeof Blob === 'undefined' ||
|
|
91
92
|
typeof URL === 'undefined'
|
|
@@ -95,6 +96,7 @@ export function createSplatSortWorker(sortSource: string): SplatSortFn {
|
|
|
95
96
|
const url = URL.createObjectURL(
|
|
96
97
|
new Blob([workerSource(sortSource)], { type: 'text/javascript' }),
|
|
97
98
|
);
|
|
99
|
+
// platform: browser default — a blob worker, guarded by the probe above
|
|
98
100
|
worker = new Worker(url);
|
|
99
101
|
/* The blob is referenced by the live worker; the URL is only the handle. */
|
|
100
102
|
URL.revokeObjectURL(url);
|