GaussianSplats3D icon indicating copy to clipboard operation
GaussianSplats3D copied to clipboard

useBuiltInControls = false not working for GaussianSplats3D.Viewer but GaussianSplats3D.DropInViewer

Open FrankEscobar opened this issue 8 months ago • 1 comments
trafficstars

I've made this test:


        const dropViewer = false;
        const sphericalHarmonicsDegree = 1;
        if(dropViewer == false)
        {
            viewer = new GaussianSplats3D.Viewer({
                'threeScene': this.scene,
                'renderer': this.renderer,
                'sharedMemoryForWorkers': false,
                'useBuiltInControls': false,
                'antialiased': true,
                'sphericalHarmonicsDegree': sphericalHarmonicsDegree,
                'camera': this.camera,
                'progressiveLoad': false
            });
        }
        else
        {
            viewer = new GaussianSplats3D.DropInViewer({
                'threeScene': this.scene,
                'renderer': this.renderer,
                'sharedMemoryForWorkers': false,
                'antialiased': true,
                'sphericalHarmonicsDegree': sphericalHarmonicsDegree,
                'camera': this.camera,
                'progressiveLoad': false
            });
        }

        const splatScenes = this.modelConfig.gaussianModels.map(gaussianModel => {
            // Configurar posición
            const position = gaussianModel.position || [-2.4, -0.4, -0.7];

            // Configurar escala
            const scale = gaussianModel.scale || [1.0, 1.0, 1.0];

            // Configurar rotación
            const eulerAngles = gaussianModel.rotation || [0, 0, 180];
            const euler = new THREE.Euler(
                THREE.MathUtils.degToRad(eulerAngles[0]),
                THREE.MathUtils.degToRad(eulerAngles[1]),
                THREE.MathUtils.degToRad(eulerAngles[2])
            );

            const quaternion = new THREE.Quaternion().setFromEuler(euler);

            return {
                'path': gaussianModel.path,
                'rotation': [quaternion._x, quaternion._y, quaternion._z, quaternion._w],
                'scale': scale,
                'position': position
            };
        });

        return viewer.addSplatScenes(splatScenes).then(() => {
            if(dropViewer==false)
                viewer.start();
            else
                this.scene.add(viewer);
        });

It seems that not using dropViewer it renders much faster on low end mobile devices, but it ignores the ThreeJS controls.

Meanwhile using it renders much slower and seems to be a bit laggy, but the control works as is expected.

Btw I installed this amazing library using npm install @mkkellogg/gaussian-splats-3d

Any tip on this? Thank you!

FrankEscobar avatar Mar 07 '25 19:03 FrankEscobar

So this behavior actually makes sense, since the DropInViewer disables the use of built-in controls: https://github.com/mkkellogg/GaussianSplats3D/blob/2dfc83e497bd76e558fe970c54464b17b5f5c689/src/DropInViewer.js#L14 The idea was that when using the the DropInViewer, the splats are just part of a larger scene, like any other 3D object, and there will most likely be some other controls being used.

There is no "nice" way (currently) to get around this, but there is a super hacky way :)

First, after creating the DropInViewer, force the useBuiltInControls property to be true:

viewer = new GaussianSplats3D.DropInViewer({
    'threeScene': this.scene,
    'renderer': this.renderer,
    'sharedMemoryForWorkers': false,
    'antialiased': true,
    'sphericalHarmonicsDegree': sphericalHarmonicsDegree,
    'camera': this.camera,
    'progressiveLoad': false
});
viewer.viewer.useBuiltInControls = true;

This will enable the controls, but since the custom render function in Viewer is not being called for drop-in mode, you need to manually render things like the focus marker that appear when you click somewhere in the scene. You'll need to do that in your main update loop:

function update() {
    // standard update loop code
    requestAnimationFrame(update);
    renderer.render(threeScene, camera);

    // Code to render focus marker starts here
    const saveAutoClear = renderer.autoClear;
    renderer.autoClear = false;
    if (viewer.viewer.sceneHelper.getFocusMarkerOpacity() > 0.0) renderer.render(viewer.viewer.sceneHelper.focusMarker, camera);
    renderer.autoClear = saveAutoClear;
}

mkkellogg avatar Mar 15 '25 16:03 mkkellogg