# 💦 Another Splat implementation for Threejs

**URL:** <https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883>\
**Category:** Showcase\
**Tags:** splat\
**Created:** [December 4, 2023, 6:51pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883 "2023-12-04T18:51:20Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [December 4, 2023, 6:51pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/1 "2023-12-04T18:51:20Z")

</div>

![Screenshot 2023-12-04 at 18.02.04](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/9/b/9b4e547b66cae0273d6de9c176277a208fbcda0c.jpeg)

demo: [Splats - CodeSandbox](https://codesandbox.io/s/nostalgic-northcutt-qp4jmf?file=/src/App.js)

it is based on [antimatter15](https://github.com/antimatter15/splat) and has been reworked to integrate with threejs.

- each splat is a regular object3d and behaves as such
- it shares data when you use the same splat multiple times
- you can have multiple splats with semi-correct depth ordering via alphatest
- it also supports alphahash for realistic ordering

i’ve made the code from a vanilla perspective, it’s a SplatLoader and a ShaderMaterial. you can already pick it up from drei source if you don’t use react+three or wait until this is available in vanilla-drei (today or tomorrow).

# updates

* * *

a first vanilla prototype sandbox: [Threejs basic example (forked) - CodeSandbox](https://codesandbox.io/s/threejs-basic-example-forked-y2xclx)

vanilla splat is available officially [https://twitter.com/0xca0a/status/1732165252710559917](https://twitter.com/0xca0a/status/1732165252710559917)

---

<div class="post-metadata">

**Author:** ![Fennec](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fennec/32/59265_2.png) [@Fennec](https://discourse.threejs.org/u/Fennec)\
**Post date:** [December 4, 2023, 8:29pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/2 "2023-12-04T20:29:18Z")

</div>

That one example with physics is just 🤯

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [December 4, 2023, 8:34pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/3 "2023-12-04T20:34:40Z")

</div>

@Fennec thanks! to do that was a major struggle, making them behave as regular Object3D’s i mean. and now that they are it can be integrated into anything.

\_\_  
and some news, a first vanilla sandbox is here: [Threejs basic example (forked) - CodeSandbox](https://codesandbox.io/s/threejs-basic-example-forked-y2xclx)

@vis_prime and i are toying with it some more and publish the vanilla api, but looks like this so far

```jsx
const loader = new SplatLoader(renderer)
const [shoeSplat, kittchenSplat] = await Promise.all([
  loader.loadAsync("nike.splat"),
  loader.loadAsync("kitchen-7k.splat")
])

const shoe1 = new Splat(shoeSplat, camera, { alphaTest: 0.1 })
shoe1.scale.setScalar(0.5)
shoe1.position.set(0, 1.6, 2)
scene.add(shoe1)

// This will re-use the same data, only one load, parse, worker & buffer
const shoe2 = new Splat(shoeSplat, camera, { alphaTest: 0.1 })
shoe2.scale.setScalar(0.5)
shoe2.position.set(0, 1.6, -1.5)
shoe2.rotation.set(Math.PI, 0, Math.PI)
scene.add(shoe2)

const kittchen = new Splat(kittchenSplat, camera)
kittchen.position.set(0, 0.25, 0)
scene.add(kittchen)

```

---

<div class="post-metadata">

**Author:** ![Fennec](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fennec/32/59265_2.png) [@Fennec](https://discourse.threejs.org/u/Fennec)\
**Post date:** [December 4, 2023, 8:38pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/4 "2023-12-04T20:38:11Z")

</div>

I know that’s why I was blown away, the fact that it behave like an Object3D open so many possibilities, not only physics.

That’s some quality work! thanks a lot for sharing.

---

<div class="post-metadata">

**Author:** ![supaworst](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/supaworst/32/37309_2.png) [@supaworst](https://discourse.threejs.org/u/supaworst)\
**Post date:** [December 4, 2023, 8:49pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/5 "2023-12-04T20:49:11Z")

</div>

Thanks for sharing, i’m really interested in it!

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [December 5, 2023, 10:29pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/6 "2023-12-05T22:29:48Z")

</div>

vanilla splat is available officially

> <https://twitter.com/0xca0a/status/1732165252710559917>

---

<div class="post-metadata">

**Author:** ![GitHubDragonFly](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/githubdragonfly/32/20752_2.png) [@GitHubDragonFly](https://discourse.threejs.org/u/GitHubDragonFly)\
**Post date:** [December 13, 2023, 12:12am UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/7 "2023-12-13T00:12:28Z")

</div>

For those who might be interested, here is a link to my online [SPLAT Viewer](https://githubdragonfly.github.io/viewers/templates/SPLAT%20Viewer.html) using vanilla-drei splat.

It is currently set for loading a single splat either locally or remotely.

The code is available [here](https://github.com/GitHubDragonFly/GitHubDragonFly.github.io/blob/d5c89bbb18cf5e41242105fdb9cd4dd46e69b5d5/viewers/templates/SPLAT%20Viewer.html) so you can see how to import it.

It also supports loading of the [Luma AI](https://lumalabs.ai/luma-web-library) links via its URL option. This will show the foreground only but if you want the background as well then download the html file and modify it yourself.

---

<div class="post-metadata">

**Author:** ![tobiascornille](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tobiascornille/32/18217_2.png) [@tobiascornille](https://discourse.threejs.org/u/tobiascornille)\
**Post date:** [March 28, 2024, 4:29pm UTC](https://discourse.threejs.org/t/another-splat-implementation-for-threejs/58883/8 "2024-03-28T16:29:46Z")

</div>

@drcmda  
Thank you very much for this implementation. I’m trying to change the color at some indices when a user does something. How should I update the state? It seems like doing this screws up the rendering, and the splat is rendered as a point cloud:

```javascript
    const { covAndColorData, covAndColorTexture, gl, bufferTextureWidth } = this.splat;
    const covAndColorData_uint8 = new Uint8Array(covAndColorData.buffer);

    const context = gl.getContext();
    const covAndColorTextureProperties = gl.properties.get(covAndColorTexture);
    context.bindTexture(context.TEXTURE_2D, covAndColorTextureProperties.__webglTexture);

    for (const i of inds) {
        covAndColorData_uint8[i * 16 + 12] = this.selectionColor[0] * 255;
        covAndColorData_uint8[i * 16 + 13] = this.selectionColor[1] * 255;
        covAndColorData_uint8[i * 16 + 14] = this.selectionColor[2] * 255;

        // Calculate the texture coordinates and dimensions of the region to update
        const xoffset = i % bufferTextureWidth;
        const yoffset = Math.floor(i / bufferTextureWidth);
        const width = 1;
        const height = 1;

        context.texSubImage2D(
          context.TEXTURE_2D,
          0,
          xoffset,
          yoffset,
          width,
          height,
          context.RGBA_INTEGER,
          context.UNSIGNED_INT,
          covAndColorData,
          i * 4,
        );
    }

    gl.resetState();

    covAndColorTexture.needsUpdate = true;

```
