Add Gaussian Splatting to Your Website


Posted by Hwan Heo on September 17, 2024
|

TL; DR

(short article)
In this tutorial, I’ll guide you how to integrate 3D Gaussian splatting into your website. Gaussian splatting is a rendering technique that represents point clouds as smooth, detailed "splats" rather than simple points, creating impressive visuals.

Don’t worry if you're not a web expert—just follow along and copy-paste the code provided!

About the Project

We’ll be using the 3D Gaussian Splatting for Three.js by mkkellogg. This package allows you to render point clouds as smooth, Gaussian splats in a 3D environment using Three.js. We’ll use this package to integrate advanced point-based rendering into our website. Now, let’s walk through the setup process.


Step-by-Step


Step 1: Project Setup (CDN-based)

For those not familiar with package management or setting up a local development environment, you can use a CDN to load the necessary libraries directly into your HTML file. Here’s how you can set up Three.js and GaussianSplats3D using CDN links:

<script type="importmap">
{
    "imports": {
        "three": "https://unpkg.com/three@0.150.0/build/three.module.js",
        "three/addons/": "https://unpkg.com/three@0.157.0/examples/jsm/",
        "GaussianSplats3D": "https://unpkg.com/@mkkellogg/gaussian-splats-3d@0.4.0/build/gaussian-splats-3d.module.js"
    }
}
</script> 

Step 2: HTML Structure

We will now initialize the WebGL renderer, set the camera’s position, and use the GaussianSplats3D viewer to load a 3D model (in .ply or .ksplat format, for example).

Note: If you follow the basic usage from the GitHub repo, the 3D content will be rendered to fill the entire page. Therefore, I’ve implemented this so the 3D scene appears only within a predefined canvas region. You can easily modify the canvas size to suit your needs.
The code below handles all of these details:

<script type="module">
    // Create a new THREE.js scene
    import * as GaussianSplats3D from 'GaussianSplats3D';
    import * as THREE from 'three';

    // Set the desired render width and height
    const renderWidth = 640;
    const renderHeight = 360;

    // Get the canvas container
    const rootElement = document.getElementById('canvasContainer');
    rootElement.style.width = renderWidth + 'px';
    rootElement.style.height = renderHeight + 'px';

    // Initialize WebGL renderer
    const renderer = new THREE.WebGLRenderer({
        antialias: true
    });
    renderer.setSize(renderWidth, renderHeight);
    renderer.setClearColor(0xf8f9fa, 1);
    rootElement.appendChild(renderer.domElement);

    // Initialize camera
    const camera = new THREE.PerspectiveCamera(65, renderWidth / renderHeight, 0.1, 500);
    camera.position.copy(new THREE.Vector3().fromArray([-1.5, -2, 3]));
    camera.up = new THREE.Vector3().fromArray([0, -1, -0.6]).normalize();
    camera.lookAt(new THREE.Vector3().fromArray([0, 3, 0]));
                    
    // Initialize the GaussianSplats3D viewer
    const viewer = new GaussianSplats3D.Viewer({
        'selfDrivenMode': true,
        'renderer': renderer,
        'camera': camera,
        'useBuiltInControls': true,
        'ignoreDevicePixelRatio': false,
        'gpuAcceleratedSort': true,
        'enableSIMDInSort': true,
        'sharedMemoryForWorkers': false,
        'integerBasedSort': true,
        'halfPrecisionCovariancesOnGPU': true,
        'dynamicScene': false,
        'webXRMode': GaussianSplats3D.WebXRMode.None,
        'renderMode': GaussianSplats3D.RenderMode.OnChange,
        'sceneRevealMode': GaussianSplats3D.SceneRevealMode.Instant,
        'antialiased': false,
        'focalAdjustment': 1.0,
        'logLevel': GaussianSplats3D.LogLevel.None,
        'sphericalHarmonicsDegree': 0,
        'enableOptionalEffects': false,
        'plyInMemoryCompressionLevel': 2,
        'freeIntermediateSplatData': false
    });
                    
    // Load a 3D scene (replace with the actual path to your model)
    viewer.addSplatScene('', {
        'position': [-0.7, -0.3, 0.9],
        'rotation': [0, 1, 0.2, 0.1],
        'scale': [3, 3, 3]
    })
    .then(() => {
        requestAnimationFrame(update);
    });

    // Update function to render the scene

    function update() {
        requestAnimationFrame(update);
        viewer.update();
        viewer.render();
    }
</script> 

Tip.

  • Set 'sharedMemoryForWorkers': false for preventing CORS error.

Example Result of Custom GS Scene

Here is the result of the above code. The loaded Gaussian Splatting is my custom captured miniature guitar. You can directly interact with the 3D Scene!

Closing

For researchers, this topic might not be of direct interest to everyone. However, in an era where personal projects and portfolios are increasingly important, I believe that learning how to add a custom Gaussian splatting scene to personal webpage could be valuable for computer vision researchers who keep an eye on the field of neural rendering. If you're curious about other research related to neural rendering, feel free to check out the other posts on my blog. That’s all for now!


You may also like,