gaussian-splat-lite 1.3.0 → 1.3.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 +44 -1
- package/dist/gaussian-splat-lite.cjs +498 -268
- package/dist/gaussian-splat-lite.cjs.map +1 -1
- package/dist/gaussian-splat-lite.min.cjs +169 -131
- package/dist/gaussian-splat-lite.min.cjs.map +1 -1
- package/dist/gaussian-splat-lite.module.js +498 -268
- package/dist/gaussian-splat-lite.module.js.map +1 -1
- package/dist/gaussian-splat-lite.module.min.js +2428 -2241
- package/dist/gaussian-splat-lite.module.min.js.map +1 -1
- package/dist/types/data/IndexedSplats.d.cts +12 -5
- package/dist/types/data/IndexedSplats.d.ts +12 -5
- package/dist/types/data/RadPagedSplats.d.cts +1 -0
- package/dist/types/data/RadPagedSplats.d.ts +1 -0
- package/dist/types/data/SplatOpacityTable.d.cts +9 -2
- package/dist/types/data/SplatOpacityTable.d.ts +9 -2
- package/dist/types/data/Splats.d.cts +1 -1
- package/dist/types/data/Splats.d.ts +1 -1
- package/dist/types/data/defines.d.cts +6 -4
- package/dist/types/data/defines.d.ts +6 -4
- package/dist/types/data/splatData.d.cts +10 -3
- package/dist/types/data/splatData.d.ts +10 -3
- package/dist/types/loaders/postDecode/builder.d.cts +1 -1
- package/dist/types/loaders/postDecode/builder.d.ts +1 -1
- package/dist/types/loaders/postDecode/protocol.d.cts +7 -5
- package/dist/types/loaders/postDecode/protocol.d.ts +7 -5
- package/dist/types/loaders/stream/StreamWorkerPool.d.cts +1 -4
- package/dist/types/loaders/stream/StreamWorkerPool.d.ts +1 -4
- package/dist/types/loaders/stream/rad-stream/RadSelectionState.d.cts +7 -4
- package/dist/types/loaders/stream/rad-stream/RadSelectionState.d.ts +7 -4
- package/dist/types/loaders/stream/rad-stream/RadStreamLoader.d.cts +20 -17
- package/dist/types/loaders/stream/rad-stream/RadStreamLoader.d.ts +20 -17
- package/dist/types/loaders/stream/rad-stream/RadStreamScheduler.d.cts +18 -2
- package/dist/types/loaders/stream/rad-stream/RadStreamScheduler.d.ts +18 -2
- package/dist/types/loaders/stream/rad-stream/RadStreamWorker.d.cts +1 -1
- package/dist/types/loaders/stream/rad-stream/RadStreamWorker.d.ts +1 -1
- package/dist/types/loaders/stream/rad-stream/prepareRadSelection.d.cts +7 -16
- package/dist/types/loaders/stream/rad-stream/prepareRadSelection.d.ts +7 -16
- package/dist/types/loaders/stream/rad-stream/radLod.d.cts +4 -2
- package/dist/types/loaders/stream/rad-stream/radLod.d.ts +4 -2
- package/dist/types/loaders/stream/rad-stream/workerHandlers.d.cts +29 -58
- package/dist/types/loaders/stream/rad-stream/workerHandlers.d.ts +29 -58
- package/dist/types/loaders/stream/sog-stream/SogStreamBatch.d.cts +0 -1
- package/dist/types/loaders/stream/sog-stream/SogStreamBatch.d.ts +0 -1
- package/dist/types/loaders/stream/sog-stream/SogStreamLoader.d.cts +2 -2
- package/dist/types/loaders/stream/sog-stream/SogStreamLoader.d.ts +2 -2
- package/dist/types/loaders/stream/sog-stream/SogStreamScheduler.d.cts +22 -2
- package/dist/types/loaders/stream/sog-stream/SogStreamScheduler.d.ts +22 -2
- package/dist/types/loaders/stream/sog-stream/sogLod.d.cts +16 -10
- package/dist/types/loaders/stream/sog-stream/sogLod.d.ts +16 -10
- package/dist/types/loaders/stream/sog-stream/sogVisibility.d.cts +4 -6
- package/dist/types/loaders/stream/sog-stream/sogVisibility.d.ts +4 -6
- package/dist/types/loaders/stream/sog-stream/workerHandlers.d.cts +2 -8
- package/dist/types/loaders/stream/sog-stream/workerHandlers.d.ts +2 -8
- package/dist/types/loaders/stream/streamOptions.d.cts +9 -8
- package/dist/types/loaders/stream/streamOptions.d.ts +9 -8
- package/docs/PostDecode.md +2 -2
- package/docs/RadStreamScheduler.md +14 -5
- package/docs/SogStreamScheduler.md +8 -6
- package/docs/SplatFileType.md +2 -0
- package/docs/SplatMesh.md +1 -1
- package/docs/Splats.md +1 -1
- package/package.json +1 -1
- package/dist/types/loaders/stream/StreamByteBudget.d.cts +0 -7
- package/dist/types/loaders/stream/StreamByteBudget.d.ts +0 -7
|
@@ -9,7 +9,7 @@ export type SogLodRange = {
|
|
|
9
9
|
};
|
|
10
10
|
export type SogLodLeaf = {
|
|
11
11
|
id: number;
|
|
12
|
-
/** Coarse to fine, with strictly
|
|
12
|
+
/** Coarse to fine, with strictly decreasing levels. */
|
|
13
13
|
lods: SogLodRange[];
|
|
14
14
|
};
|
|
15
15
|
export type SogLodNode = {
|
|
@@ -25,8 +25,7 @@ export type SogLodFile = {
|
|
|
25
25
|
export type SogLodManifest = {
|
|
26
26
|
tree: SogLodNode;
|
|
27
27
|
leaves: SogLodLeaf[];
|
|
28
|
-
|
|
29
|
-
upgradeRatios: number[];
|
|
28
|
+
lodLevels: number;
|
|
30
29
|
files: SogLodFile[];
|
|
31
30
|
environment?: string;
|
|
32
31
|
};
|
|
@@ -38,14 +37,13 @@ export type SogLodIndex = {
|
|
|
38
37
|
leafOffsets: Uint32Array;
|
|
39
38
|
/** Per level: level, file, offset, count. */
|
|
40
39
|
lods: Float64Array;
|
|
41
|
-
|
|
42
|
-
upgradeRatios: Float32Array;
|
|
40
|
+
lodLevels: number;
|
|
43
41
|
urls: string[];
|
|
44
42
|
counts: Float64Array;
|
|
45
43
|
environment?: string;
|
|
46
44
|
};
|
|
47
45
|
/** Scheduler metadata; the complete spatial tree stays in the LOD worker. */
|
|
48
|
-
export type SogLodMetadata = Omit<SogLodIndex, "nodes" | "
|
|
46
|
+
export type SogLodMetadata = Omit<SogLodIndex, "nodes" | "lodLevels"> & {
|
|
49
47
|
/** Root min XYZ and max XYZ. */
|
|
50
48
|
bounds: Float64Array;
|
|
51
49
|
};
|
|
@@ -63,7 +61,15 @@ export declare function parseSogLodManifest(
|
|
|
63
61
|
): SogLodManifest;
|
|
64
62
|
export type SogVisibleLeaf = {
|
|
65
63
|
leaf: SogLodLeaf;
|
|
66
|
-
|
|
64
|
+
/** World-space distance to the region, compensated for the camera's field of view. */
|
|
65
|
+
distance: number;
|
|
66
|
+
};
|
|
67
|
+
export type SogBudgetMode = "target" | "limit";
|
|
68
|
+
export type SogLodOptions = {
|
|
69
|
+
budget: number;
|
|
70
|
+
splatBudgetMode: SogBudgetMode;
|
|
71
|
+
lodBaseDistance: number;
|
|
72
|
+
lodMultiplier: number;
|
|
67
73
|
};
|
|
68
74
|
/** Reuse cached refinements up to the target, then split gaps of four or more. */
|
|
69
75
|
export declare function resolveSogLod(
|
|
@@ -77,9 +83,9 @@ export declare function resolveSogLod(
|
|
|
77
83
|
/** Wait until range is attached before requesting the next LOD. */
|
|
78
84
|
refinement?: boolean;
|
|
79
85
|
};
|
|
80
|
-
/**
|
|
86
|
+
/** Select distance bands, fitting their common base distance to the splat budget. */
|
|
81
87
|
export declare function selectSogLods(
|
|
82
88
|
visible: SogVisibleLeaf[],
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
lodLevels: number,
|
|
90
|
+
options: SogLodOptions,
|
|
85
91
|
): Map<number, SogLodRange>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as THREE from "three";
|
|
2
|
-
import type { SogLodIndex } from "./sogLod.cjs";
|
|
2
|
+
import type { SogLodIndex, SogLodOptions } from "./sogLod.cjs";
|
|
3
3
|
export type SogCamera = {
|
|
4
4
|
modelView: number[];
|
|
5
5
|
projection: number[];
|
|
@@ -11,6 +11,7 @@ export type SogView = {
|
|
|
11
11
|
cameras: SogCamera[];
|
|
12
12
|
shown: boolean;
|
|
13
13
|
};
|
|
14
|
+
export type SogLodRequest = SogLodOptions & { view: SogView };
|
|
14
15
|
/**
|
|
15
16
|
* Capture the cameras that see the group without traversing the manifest or
|
|
16
17
|
* reducing matrix precision. WebXR selects detail from each eye's current pose and frustum.
|
|
@@ -31,13 +32,10 @@ export declare class SogVisibility {
|
|
|
31
32
|
private readonly closest;
|
|
32
33
|
private readonly inverseModelView;
|
|
33
34
|
constructor(
|
|
34
|
-
manifest: Pick<
|
|
35
|
-
SogLodIndex,
|
|
36
|
-
"nodes" | "leafOffsets" | "lods" | "upgradeRatios"
|
|
37
|
-
>,
|
|
35
|
+
manifest: Pick<SogLodIndex, "nodes" | "leafOffsets" | "lods" | "lodLevels">,
|
|
38
36
|
);
|
|
39
37
|
private prepareCameras;
|
|
40
38
|
private collect;
|
|
41
39
|
/** Transfer only [leaf ID, LOD ordinal] pairs in loading priority order. */
|
|
42
|
-
select(
|
|
40
|
+
select(request: SogLodRequest): Uint32Array;
|
|
43
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as THREE from "three";
|
|
2
|
-
import type { SogLodIndex } from "./sogLod.js";
|
|
2
|
+
import type { SogLodIndex, SogLodOptions } from "./sogLod.js";
|
|
3
3
|
export type SogCamera = {
|
|
4
4
|
modelView: number[];
|
|
5
5
|
projection: number[];
|
|
@@ -11,6 +11,7 @@ export type SogView = {
|
|
|
11
11
|
cameras: SogCamera[];
|
|
12
12
|
shown: boolean;
|
|
13
13
|
};
|
|
14
|
+
export type SogLodRequest = SogLodOptions & { view: SogView };
|
|
14
15
|
/**
|
|
15
16
|
* Capture the cameras that see the group without traversing the manifest or
|
|
16
17
|
* reducing matrix precision. WebXR selects detail from each eye's current pose and frustum.
|
|
@@ -31,13 +32,10 @@ export declare class SogVisibility {
|
|
|
31
32
|
private readonly closest;
|
|
32
33
|
private readonly inverseModelView;
|
|
33
34
|
constructor(
|
|
34
|
-
manifest: Pick<
|
|
35
|
-
SogLodIndex,
|
|
36
|
-
"nodes" | "leafOffsets" | "lods" | "upgradeRatios"
|
|
37
|
-
>,
|
|
35
|
+
manifest: Pick<SogLodIndex, "nodes" | "leafOffsets" | "lods" | "lodLevels">,
|
|
38
36
|
);
|
|
39
37
|
private prepareCameras;
|
|
40
38
|
private collect;
|
|
41
39
|
/** Transfer only [leaf ID, LOD ordinal] pairs in loading priority order. */
|
|
42
|
-
select(
|
|
40
|
+
select(request: SogLodRequest): Uint32Array;
|
|
43
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SplatResult } from "../../../data/defines.cjs";
|
|
2
2
|
import type { SplatLoadArgs, SplatLoadStatus } from "../../loadTypes.cjs";
|
|
3
|
-
import type {
|
|
3
|
+
import type { SogLodRequest } from "./sogVisibility.cjs";
|
|
4
4
|
export type SogChunkInfo = {
|
|
5
5
|
numSplats: number;
|
|
6
6
|
numSh: number;
|
|
@@ -63,11 +63,5 @@ export declare function createSogStreamHandlers(
|
|
|
63
63
|
counts: Float64Array;
|
|
64
64
|
environment?: string;
|
|
65
65
|
};
|
|
66
|
-
selectSogLod: (
|
|
67
|
-
view,
|
|
68
|
-
budget,
|
|
69
|
-
}: {
|
|
70
|
-
view: SogView;
|
|
71
|
-
budget: number;
|
|
72
|
-
}) => Uint32Array<ArrayBufferLike>;
|
|
66
|
+
selectSogLod: (request: SogLodRequest) => Uint32Array<ArrayBufferLike>;
|
|
73
67
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SplatResult } from "../../../data/defines.js";
|
|
2
2
|
import type { SplatLoadArgs, SplatLoadStatus } from "../../loadTypes.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { SogLodRequest } from "./sogVisibility.js";
|
|
4
4
|
export type SogChunkInfo = {
|
|
5
5
|
numSplats: number;
|
|
6
6
|
numSh: number;
|
|
@@ -63,11 +63,5 @@ export declare function createSogStreamHandlers(
|
|
|
63
63
|
counts: Float64Array;
|
|
64
64
|
environment?: string;
|
|
65
65
|
};
|
|
66
|
-
selectSogLod: (
|
|
67
|
-
view,
|
|
68
|
-
budget,
|
|
69
|
-
}: {
|
|
70
|
-
view: SogView;
|
|
71
|
-
budget: number;
|
|
72
|
-
}) => Uint32Array<ArrayBufferLike>;
|
|
66
|
+
selectSogLod: (request: SogLodRequest) => Uint32Array<ArrayBufferLike>;
|
|
73
67
|
};
|
|
@@ -10,7 +10,7 @@ export type StreamSchedulerOptions = {
|
|
|
10
10
|
/** Milliseconds to retain unused data after fade-out; defaults to 2000. */
|
|
11
11
|
cooldownMs?: number;
|
|
12
12
|
fadeDurationMs?: number;
|
|
13
|
-
/**
|
|
13
|
+
/** Maximum simultaneous downloads/decodes; defaults to 4. */
|
|
14
14
|
maxConcurrentLoads?: number;
|
|
15
15
|
onChange?: () => void;
|
|
16
16
|
onError?: (error: unknown, url: string) => void;
|
|
@@ -21,11 +21,17 @@ export type StreamStats = {
|
|
|
21
21
|
residentMeshes: number;
|
|
22
22
|
/** Decoded chunks, including cached chunks that are not currently drawn. */
|
|
23
23
|
residentChunks: number;
|
|
24
|
-
/** Retained CPU
|
|
24
|
+
/** Retained CPU data, excluding pending copies and WASM memory. */
|
|
25
|
+
residentCpuBytes: number;
|
|
26
|
+
/** Estimated GPU storage for resident streaming data; excludes renderer buffers. */
|
|
27
|
+
residentGpuBytes: number;
|
|
28
|
+
/** Sum of residentCpuBytes and residentGpuBytes. */
|
|
25
29
|
residentBytes: number;
|
|
26
|
-
/**
|
|
30
|
+
/** Estimated in-flight or ready copies awaiting publication into source storage. */
|
|
27
31
|
pendingBytes: number;
|
|
28
32
|
loadingChunks: number;
|
|
33
|
+
/** Ready share of the current view's requested detail, from 0 to 1. Changes with the view. */
|
|
34
|
+
loadProgress: number;
|
|
29
35
|
downloadedBytes: number;
|
|
30
36
|
peakWasmMemoryBytes: number;
|
|
31
37
|
};
|
|
@@ -36,11 +42,6 @@ export declare function streamSettings(options: StreamSchedulerOptions): {
|
|
|
36
42
|
fadeDurationMs: number;
|
|
37
43
|
maxConcurrentLoads: number;
|
|
38
44
|
};
|
|
39
|
-
/** Bound queued decode/extraction copies independently of per-update publication. */
|
|
40
|
-
export declare function streamPendingLimit(
|
|
41
|
-
concurrency: number,
|
|
42
|
-
unitBytes?: number,
|
|
43
|
-
): number;
|
|
44
45
|
/** Format errors are permanent; transient failures retry with capped backoff. */
|
|
45
46
|
export declare function streamRetryAt(error: unknown, failures: number): number;
|
|
46
47
|
export declare function notifyStreamChange(
|
|
@@ -10,7 +10,7 @@ export type StreamSchedulerOptions = {
|
|
|
10
10
|
/** Milliseconds to retain unused data after fade-out; defaults to 2000. */
|
|
11
11
|
cooldownMs?: number;
|
|
12
12
|
fadeDurationMs?: number;
|
|
13
|
-
/**
|
|
13
|
+
/** Maximum simultaneous downloads/decodes; defaults to 4. */
|
|
14
14
|
maxConcurrentLoads?: number;
|
|
15
15
|
onChange?: () => void;
|
|
16
16
|
onError?: (error: unknown, url: string) => void;
|
|
@@ -21,11 +21,17 @@ export type StreamStats = {
|
|
|
21
21
|
residentMeshes: number;
|
|
22
22
|
/** Decoded chunks, including cached chunks that are not currently drawn. */
|
|
23
23
|
residentChunks: number;
|
|
24
|
-
/** Retained CPU
|
|
24
|
+
/** Retained CPU data, excluding pending copies and WASM memory. */
|
|
25
|
+
residentCpuBytes: number;
|
|
26
|
+
/** Estimated GPU storage for resident streaming data; excludes renderer buffers. */
|
|
27
|
+
residentGpuBytes: number;
|
|
28
|
+
/** Sum of residentCpuBytes and residentGpuBytes. */
|
|
25
29
|
residentBytes: number;
|
|
26
|
-
/**
|
|
30
|
+
/** Estimated in-flight or ready copies awaiting publication into source storage. */
|
|
27
31
|
pendingBytes: number;
|
|
28
32
|
loadingChunks: number;
|
|
33
|
+
/** Ready share of the current view's requested detail, from 0 to 1. Changes with the view. */
|
|
34
|
+
loadProgress: number;
|
|
29
35
|
downloadedBytes: number;
|
|
30
36
|
peakWasmMemoryBytes: number;
|
|
31
37
|
};
|
|
@@ -36,11 +42,6 @@ export declare function streamSettings(options: StreamSchedulerOptions): {
|
|
|
36
42
|
fadeDurationMs: number;
|
|
37
43
|
maxConcurrentLoads: number;
|
|
38
44
|
};
|
|
39
|
-
/** Bound queued decode/extraction copies independently of per-update publication. */
|
|
40
|
-
export declare function streamPendingLimit(
|
|
41
|
-
concurrency: number,
|
|
42
|
-
unitBytes?: number,
|
|
43
|
-
): number;
|
|
44
45
|
/** Format errors are permanent; transient failures retry with capped backoff. */
|
|
45
46
|
export declare function streamRetryAt(error: unknown, failures: number): number;
|
|
46
47
|
export declare function notifyStreamChange(
|
package/docs/PostDecode.md
CHANGED
|
@@ -43,9 +43,9 @@ Read these from `splat`:
|
|
|
43
43
|
| `splat.opacity` | `float` | Opacity as stored in the model, which can be above 1 |
|
|
44
44
|
| `splat.alpha` | `float` | Opacity from 0 (transparent) to 1 (opaque) |
|
|
45
45
|
| `splat.color` | `vec3` | RGB color |
|
|
46
|
-
| `splat.sh.coefficient(index)` | `vec3` | One of the
|
|
46
|
+
| `splat.sh.coefficient(index)` | `vec3` | One of the 24 view-dependent color coefficients (indices 0–23, SH1–SH4) |
|
|
47
47
|
|
|
48
|
-
`splat.sh.map((coefficient, { degree }) => ...)` builds a calculation for all
|
|
48
|
+
`splat.sh.map((coefficient, { degree }) => ...)` builds a calculation for all 24 coefficients at once. Only the ones the model has are updated.
|
|
49
49
|
|
|
50
50
|
## Returning changes
|
|
51
51
|
|
|
@@ -10,6 +10,9 @@ import { RadStreamScheduler } from "gaussian-splat-lite";
|
|
|
10
10
|
const streaming = new RadStreamScheduler({
|
|
11
11
|
url: "/models/scene.rad",
|
|
12
12
|
splatBudget: 3_000_000,
|
|
13
|
+
splatBudgetTolerance: 0.1, // Allow up to 10% extra Splats; 0 forbids overshoot.
|
|
14
|
+
maxResidentCpuBytes: 2 * 1024 * 1024 * 1024, // 2 GiB
|
|
15
|
+
maxResidentGpuBytes: 1024 * 1024 * 1024, // 1 GiB
|
|
13
16
|
});
|
|
14
17
|
scene.add(streaming.group);
|
|
15
18
|
streaming.setCamera(camera);
|
|
@@ -72,16 +75,21 @@ renderer.setAnimationLoop(() => {
|
|
|
72
75
|
| `url` / `file` / `fileBytes` | Exactly one required | URL, `Blob`/`File`, or complete `Uint8Array`/`ArrayBuffer` |
|
|
73
76
|
| `resolveFile` | Relative URLs | Supply the `.radc` pages of a split scene yourself: `(filename, signal) => URL \| Blob \| Uint8Array \| ArrayBuffer`, directly or as a promise |
|
|
74
77
|
| `group` | New `THREE.Group` | Group that holds the scene |
|
|
75
|
-
| `splatBudget` | `3_000_000` |
|
|
78
|
+
| `splatBudget` | `3_000_000` | Target number of Splats. Higher values show more detail and use more memory |
|
|
79
|
+
| `splatBudgetTolerance` | `0.1` | Allowed fractional overshoot of `splatBudget`. `0.1` allows up to 10% extra Splats; `0` keeps each new selection within `splatBudget`. Must be finite and nonnegative |
|
|
80
|
+
| `maxResidentCpuBytes` | 2 GiB | CPU memory budget for cached data, in bytes. Set a positive integer when creating the scheduler |
|
|
81
|
+
| `maxResidentGpuBytes` | 1 GiB | GPU memory budget for cached data, in bytes. Set a positive integer when creating the scheduler |
|
|
76
82
|
| `fadeDurationMs` | `200` | Duration of the fade when the scene first appears and when detail changes; `0` switches instantly |
|
|
77
|
-
| `cooldownMs` | `2000` | How long detail
|
|
78
|
-
| `maxConcurrentLoads` | `4` | Maximum number of loads
|
|
83
|
+
| `cooldownMs` | `2000` | How long unused detail stays ready for reuse; it can be released sooner when either memory budget is reached. `0` releases it at once |
|
|
84
|
+
| `maxConcurrentLoads` | `4` | Maximum number of simultaneous loads, regardless of page size. |
|
|
79
85
|
| `manager` | `THREE.DefaultLoadingManager` | Three.js loading manager, including its URL modifiers |
|
|
80
86
|
| `requestHeader` / `withCredentials` | `{}` / `false` | Request settings. Sensitive settings are not sent to other origins |
|
|
81
87
|
| `onChange` | — | Called when the scene needs a redraw |
|
|
82
88
|
| `onError` | Logs to the console | Called when loading fails: `(error, url)` |
|
|
83
89
|
|
|
84
|
-
Detail
|
|
90
|
+
Detail already on screen stays visible while its replacement loads, if both memory budgets allow. At the limit, the scene may temporarily show less detail. During a fade, old and new detail overlap, so the visible count can briefly exceed the selection limit. Use both `splatBudgetTolerance: 0` and `fadeDurationMs: 0` to keep new selections and their transitions within `splatBudget`.
|
|
91
|
+
|
|
92
|
+
Unused detail is released after `cooldownMs`, including while hidden, and loads again when needed.
|
|
85
93
|
|
|
86
94
|
## Properties and methods
|
|
87
95
|
|
|
@@ -89,6 +97,7 @@ Detail that is already on screen stays there while its replacement loads. During
|
|
|
89
97
|
| --- | --- |
|
|
90
98
|
| `group` | Group that holds the scene |
|
|
91
99
|
| `splatBudget` | Change it at any time to adjust detail, even while the camera is still. Must be a positive integer |
|
|
100
|
+
| `splatBudgetTolerance` | Change the allowed overshoot at any time without reloading. `0` forbids overshoot |
|
|
92
101
|
| `initialized` | Resolves when the scene is set up; rejects for invalid or unsupported files |
|
|
93
102
|
| `firstRenderable` | Resolves when the first data is on screen, or the scene is empty; rejects if the first data cannot be loaded. Keep calling `update()` while you wait |
|
|
94
103
|
| `setCamera(camera)` / `deleteCamera(camera)` | Add or remove a camera that chooses detail. `hasCamera(camera)` and `cameras` report the registered ones |
|
|
@@ -97,7 +106,7 @@ Detail that is already on screen stays there while its replacement loads. During
|
|
|
97
106
|
| `update()` | Advance detail selection, loading, and fades. Call it before every render; it throws if no camera is registered |
|
|
98
107
|
| `getBoundingBox()` | Approximate box around the scene, in the group's coordinates; empty until the first data loads |
|
|
99
108
|
| `getGlobalIndex(mesh, renderedIndex)` | Convert a picking hit into a node index that stays the same for the whole RAD file |
|
|
100
|
-
| `stats` |
|
|
109
|
+
| `stats` | Visible Splats, loading progress, and estimated CPU/GPU cache sizes (`residentCpuBytes` / `residentGpuBytes`) |
|
|
101
110
|
| `dispose()` | Stop loading and release the scene. Pending `initialized` and `firstRenderable` promises reject with `AbortError` |
|
|
102
111
|
|
|
103
112
|
### On-demand rendering
|
|
@@ -48,7 +48,10 @@ In WebXR, register `renderer.xr.getCamera()` in place of your camera, as shown f
|
|
|
48
48
|
| --- | --- | --- |
|
|
49
49
|
| `url` | Required | URL of the scene's `lod-meta.json` |
|
|
50
50
|
| `group` | New `THREE.Group` | Group that holds the scene |
|
|
51
|
-
| `splatBudget` | `3_000_000` |
|
|
51
|
+
| `splatBudget` | `3_000_000` | Splat budget, including the environment. Higher values allow more detail and use more memory |
|
|
52
|
+
| `splatBudgetMode` | `"target"` | `"target"` adjusts the distance bands to fill the budget. `"limit"` uses the configured distance bands and only reduces detail when they exceed the budget |
|
|
53
|
+
| `lodBaseDistance` | `100` | Base LOD distance in world units for `"limit"` mode, compensated for the camera's field of view. Higher values retain finer detail farther away. Must be finite and positive |
|
|
54
|
+
| `lodMultiplier` | `2` | Distance multiplier between successive LOD levels in both modes. Must be finite and at least `1` |
|
|
52
55
|
| `fadeDurationMs` | `200` | Duration of the fade when the scene first appears and when detail changes; `0` switches instantly |
|
|
53
56
|
| `cooldownMs` | `2000` | How long detail that is no longer shown stays in memory, ready for reuse; `0` releases it at once |
|
|
54
57
|
| `maxConcurrentLoads` | `4` | Maximum number of loads in progress at the same time |
|
|
@@ -58,22 +61,21 @@ In WebXR, register `renderer.xr.getCamera()` in place of your camera, as shown f
|
|
|
58
61
|
| `onError` | Logs to the console | Called when loading fails: `(error, url)` |
|
|
59
62
|
| `loadChunk` | Built-in loader | Load the scene's files yourself: `(url, signal) => Promise<Splats>` |
|
|
60
63
|
|
|
61
|
-
The budget is a target, not a hard limit: the available detail levels, fades, and the environment can take the scene above it. It limits what is shown, not total memory: detail kept for reuse takes memory too.
|
|
62
|
-
|
|
63
|
-
Some parts of a scene exist only at finer detail levels. They can be empty from far away and fade in as the camera approaches.
|
|
64
|
-
|
|
65
64
|
## Properties and methods
|
|
66
65
|
|
|
67
66
|
| API | Description |
|
|
68
67
|
| --- | --- |
|
|
69
68
|
| `group` | Group that holds the scene |
|
|
70
69
|
| `splatBudget` | Change it at any time to adjust detail. Must be a positive integer; includes the environment |
|
|
70
|
+
| `splatBudgetMode` | Switch between `"target"` and `"limit"` without reloading |
|
|
71
|
+
| `lodBaseDistance` | Change the base LOD distance in `"limit"` mode without reloading |
|
|
72
|
+
| `lodMultiplier` | Change the distance spacing between LOD levels in both modes without reloading |
|
|
71
73
|
| `initialized` | Resolves when the index is loaded; rejects for invalid input |
|
|
72
74
|
| `firstRenderable` | Resolves when the first data is on screen, or the scene is empty; rejects if the first data cannot be loaded. Keep calling `update()` while you wait |
|
|
73
75
|
| `setCamera(camera)` / `deleteCamera(camera)` | Add or remove a camera that chooses detail. `hasCamera(camera)` and `cameras` report the registered ones |
|
|
74
76
|
| `update()` | Advance detail selection, loading, and fades. Call it before every render; it throws if no camera is registered |
|
|
75
77
|
| `getBoundingBox()` | Box around the scene, in the group's coordinates; available once `initialized` resolves |
|
|
76
|
-
| `stats` |
|
|
78
|
+
| `stats` | Visible Splats, loading progress, and estimated CPU/GPU cache sizes (`residentCpuBytes` / `residentGpuBytes`) |
|
|
77
79
|
| `dispose()` | Stop loading and release the scene. Pending `initialized` and `firstRenderable` promises reject with `AbortError` |
|
|
78
80
|
|
|
79
81
|
### On-demand rendering
|
package/docs/SplatFileType.md
CHANGED
|
@@ -11,6 +11,8 @@ The model formats you can load:
|
|
|
11
11
|
| `SplatFileType.SOG` | `"sog"` | `.sog`, or a SOG `meta.json` with its images |
|
|
12
12
|
| `SplatFileType.RAD` | `"rad"` | `.rad` |
|
|
13
13
|
|
|
14
|
+
PLY and SPZ support view-dependent color up to SH4 on WebGL, WebGPU, and the WebGL2 fallback. RAD and SOG support up to SH3. Models render all their available coefficients by default; set [`mesh.maxSh`](SplatMesh.md#properties) to limit the degree.
|
|
15
|
+
|
|
14
16
|
The format is normally detected from the URL or `fileName`, so you rarely need this. Set it when the name does not show the format:
|
|
15
17
|
|
|
16
18
|
```js
|
package/docs/SplatMesh.md
CHANGED
|
@@ -59,7 +59,7 @@ Choose at most one of `url`, `file`, `fileBytes`, or `splats`; combining them th
|
|
|
59
59
|
| `numSplats` | `number` | Current Splat count |
|
|
60
60
|
| `recolor` | `THREE.Color(1, 1, 1)` | Color multiplier for the whole model |
|
|
61
61
|
| `opacity` | `1` | Opacity multiplier for the whole model |
|
|
62
|
-
| `maxSh` | `
|
|
62
|
+
| `maxSh` | `4` | Limit view-dependent color detail to SH0–SH4; `0` uses the base color only |
|
|
63
63
|
| `edits` | `SplatEdit[] \| null` | Explicit list of [edits](SplatEdit.md) for this mesh |
|
|
64
64
|
| `splats` | `Splats \| undefined` | The model's [Splats](Splats.md) data |
|
|
65
65
|
| `needsUpdate` | `boolean` setter | Set to `true` to force a refresh |
|
package/docs/Splats.md
CHANGED
|
@@ -49,7 +49,7 @@ Calling `initialize()` again or `dispose()` cancels a load still in progress; it
|
|
|
49
49
|
## Data rules
|
|
50
50
|
|
|
51
51
|
- **Indices are not file order.** Splats are reordered while loading. Use `getSourceIndex(index)`, or a picking hit's `sourceIndex`, to get the ID from the original file. Passing existing `Splats` to a mesh keeps their order.
|
|
52
|
-
- **Reads return copies.** `getSplat()` returns new `center`, `scales`, `quaternion`, `opacity`, `color`, and `sh` values on each call; changing them does not change the model. `sh` holds 0, 3, 8, or
|
|
52
|
+
- **Reads return copies.** `getSplat()` returns new `center`, `scales`, `quaternion`, `opacity`, `color`, and `sh` values on each call; changing them does not change the model. `sh` holds 0, 3, 8, 15, or 24 RGB coefficients, depending on the model's degree (SH0–SH4).
|
|
53
53
|
- **`forEachSplat()` reuses its objects.** The same objects are passed for every Splat, so clone anything you want to keep after the callback returns.
|
|
54
54
|
- **Streamed data is read-only.** Data from [RadStreamScheduler](RadStreamScheduler.md) or [SogStreamScheduler](SogStreamScheduler.md) cannot be reinitialized.
|
|
55
55
|
- **Bounds live on the mesh.** Use [`mesh.getBoundingBox()`](SplatMesh.md#bounding-box).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gaussian-splat-lite",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Three.js Gaussian Splatting renderer with WebGPU/WebGL2, GPU sorting, streaming LOD, and high-precision GIS/ECEF support. Supports PLY, SPZ, SOG and RAD.",
|
|
5
5
|
"author": "William Liu <lyz15972107087@gmail.com>",
|
|
6
6
|
"type": "module",
|