LavaLamp
A small MarchingCubes example using three.js’s marching cubes addon.
<script lang="ts">
import Scene from './Scene.svelte'
import type { Axis } from './MarchingPlane'
import { Canvas } from '@threlte/core'
import { Pane, Folder, List, Slider } from 'svelte-tweakpane-ui'
let ballCount = $state(15)
let isolation = $state(80)
let planeAxis: Axis = $state('y')
let resolution = $state(35)
type AxisOptions = {
[Key in Axis]: Key
}
const axisOptions: AxisOptions = {
x: 'x',
y: 'y',
z: 'z'
}
</script>
<div>
<Pane
position="fixed"
title="Lava Lamp"
>
<Slider
label="ball count"
bind:value={ballCount}
min={3}
max={25}
step={1}
/>
<Slider
label="isolation"
bind:value={isolation}
min={40}
max={100}
step={1}
/>
<Slider
label="resolution"
bind:value={resolution}
min={10}
max={50}
step={1}
/>
<Folder title="Plane">
<List
label="Axis"
bind:value={planeAxis}
options={axisOptions}
/>
</Folder>
</Pane>
<Canvas>
<Scene
{ballCount}
{planeAxis}
{resolution}
{isolation}
/>
</Canvas>
</div>
<style>
div {
height: 100%;
}
</style>The addon is a little too limited to be ported into a component but this example shows how it might be incorporated into threlte.
Placement
MarchingCubes defines a space from -1 to 1 for all 3 axes.
MarchingPlane
The original example only allows for planes positioned at x = -1, y = -1, and z = -1.
MarchingCube
<MarchingCube>s can be placed anywhere in the MarchingCubes space. If they are placed outside this range they may be cutoff or not show altogether.
Even though MarchingCube appears as a ball, it is called Cube to be inline with drei’s
MarchingCubes abstration.
Materials
The example above utilizes vertex coloring but the original three.js example has support for any kind of material. Vertex coloring requires a little more memory since each vertex now carries a color with it. If you’re not using vertex colors, you can leave enableColors turned off. The <MarchingCubes> component uses the same default material that Three.Meshes do. Setting different materials is the same process as setting different materials for <T.Mesh>.
<MarchingCubes>
<T.MeshNormalMaterial />
<T is={cube} />
</MarchingCubes>If you’re using a material with a texture, you will need to set enableUvs to true.
<MarchingCubes enableUvs>
<T.MeshNormalMaterial map={texture} />
<MarchingCube />
</MarchingCubes>Note that the example above enables both uvs and vertex coloring for demonstration purposes. You can set these to false in the constructor to save on space.
<script>
// ...
// don't allocate space for vertex colors nor uvs
const marchingCubes = new MarchingCubes(resolution, material, false, false, 20_000)
// ...
</script>