mkkellogg / GaussianSplats3D

Three.js-based implementation of 3D Gaussian splatting
MIT License
1.54k stars 199 forks source link

Adding scenes to a dynamicScene viewer fails with "offset is out of bounds" #380

Open Nyveon opened 3 days ago

Nyveon commented 3 days ago

Hi! First off, thank you for creating and maintaining this amazing tool. It has been incredibly useful to me, and I truly appreciate all the effort you’ve put into it! c:

Context

When using a viewer in dynamicScene mode, adding another scene (after one or more scenes are already loaded) results in an error. This issue seems potentially related to https://github.com/mkkellogg/GaussianSplats3D/issues/346.

Details

The following error occurs consistently:

Uncaught RangeError: offset is out of bounds
    at Uint32Array.set (<anonymous>)
    at mn.gatherSceneNodesForSort (Viewer.js:2042:46)
    at mn.runSplatSort (Viewer.js:1857:60)
    at mn.update (Viewer.js:1609:14)
    at An.onBeforeRender (DropInViewer.js:124:16)
    at Kt (three.module.js:16255:11)
    at Zt (three.module.js:16245:6)
    at Xt (three.module.js:16094:36)
    at im.render (three.module.js:15912:5)
    at update (viewersidebyside.html:159:15)

Viewer.js:1135 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'then')
    at Viewer.js:1135:54

The error seems to originate from this line of code in the viewer: https://github.com/mkkellogg/GaussianSplats3D/blob/f6f4adea2e0a5745f942767214c7d3b335a10751/src/Viewer.js#L2051

I suspect the root cause lies elsewhere, since the arrays sortWorkerIndexestoSort and allSplatsSortBuffer are already mismatched at that point. But here are my observations about the mismatch anyways:

totalSplatCount this.sortWorkerIndexesToSort allSplatsSortBuffer
Static - Initial load 175745 Uint32Array(175745) [0, 1, 2, 3, ... Uint32Array(175745) [0, 1, 2, 3, ...
Static - Add scene 351490 Uint32Array(351490) [0, 1, 2, 3, ... Uint32Array(351490) [0, 1, 2, 3, ...
*Dynamic - Initial load 175745 Uint32Array(175745) [0, 1, 2, 3, ... Uint32Array(175745) [0, 1, 2, 3, ...
Dynamic - Add scene 351490 Uint32Array(175745) [175676, 175735, 172256, 172260, ... Uint32Array(175745) [0, 1, 2, 3, ...

*With dynamic mode active the the initial load hits that line 5 times vs. the static scenes 1. Not sure if that's expected behaviour?

Reproducible example

I've uploaded an example here. It's based on the code from the demos folder of your repo, so hopefully it should be easy for you to navigate. The source code can be read here and the most relevant file to check out would be viewersidebyside.html .

Note: if no splats at all load in the first time, try reloading the page to make sure the CORS trick kicks in

To reproduce the error, open "Side by side comparison" and then:

Observations:

Here are some extra observations that may (or may not) help narrow the issue down:

I wish I could offer more insights, but I know nothing of WASM, web workers, or how the splat sorting works. So, if there's anything else I can do to help identify and solve the issue, please let me know!