Rendering Points
<script>
import { Canvas } from '@threlte/core'
import Scene from './Scene.svelte'
</script>
<div>
<Canvas>
<Scene />
</Canvas>
</div>
<style>
div {
height: 100%;
}
</style>
<script lang="ts">
import { T } from '@threlte/core'
import { Align, OrbitControls } from '@threlte/extras'
const size = 30
const count = size ** 3
const positions = new Float32Array(count * 3)
// 3D math squiggles
for (let i = 0; i < count; i++) {
// 1D to 3D array
let x = i / (size * size)
let y = (i / size) % size
let z = i % size
const vx =
Math.sin(Math.abs(size - x) * 0.1) * Math.sin(Math.abs(size - y) * 0.1) * 10 +
Math.random() * 0.1
const vy =
Math.sin(Math.abs(size - x) * 0.3) * Math.sin(Math.abs(size - y) * 0.3) * 10 +
Math.random() * 0.1
const vz = y + Math.random() * 0.01 * z
//x
positions[i * 3 + 0] = vx
//y
positions[i * 3 + 1] = vy
//z
positions[i * 3 + 2] = vz
}
</script>
<T.PerspectiveCamera
makeDefault
position={[50, 50, 50]}
fov={15}
>
<OrbitControls autoRotate />
</T.PerspectiveCamera>
<T.DirectionalLight
position.y={10}
position.z={10}
/>
<Align>
<T.Points>
<T.BufferGeometry>
<T.BufferAttribute
args={[positions, 3]}
attach={(parent, self) => {
parent.setAttribute('position', self)
return () => {
// cleanup function called when ref changes or the component unmounts
// https://threlte.xyz/docs/reference/core/t#attach
}
}}
/>
</T.BufferGeometry>
<T.PointsMaterial size={0.25} />
</T.Points>
</Align>
<script lang="ts">
import { T } from '@threlte/core'
import { Align, OrbitControls } from '@threlte/extras'
import { BufferGeometry, Vector3 } from 'three'
const size = 30
const count = size ** 3
const vectorPositions: Vector3[] = []
// 3D math squiggles
for (let i = 0; i < count; i++) {
// 1D to 3D array
let x = i / (size * size)
let y = (i / size) % size
let z = i % size
const vx =
Math.sin(Math.abs(size - x) * 0.1) * Math.sin(Math.abs(size - y) * 0.1) * 10 +
Math.random() * 0.1
const vy =
Math.sin(Math.abs(size - x) * 0.3) * Math.sin(Math.abs(size - y) * 0.3) * 10 +
Math.random() * 0.1
const vz = y + Math.random() * 0.01 * z
vectorPositions.push(new Vector3(vx, vy, vz))
}
const pointsBufferGeometry = new BufferGeometry().setFromPoints(vectorPositions)
</script>
<T.PerspectiveCamera
makeDefault
position={[50, 50, 50]}
fov={15}
>
<OrbitControls autoRotate />
</T.PerspectiveCamera>
<T.DirectionalLight
position.y={10}
position.z={10}
/>
<Align>
<T.Points>
<T is={pointsBufferGeometry} />
<T.PointsMaterial size={0.25} />
</T.Points>
</Align>
Using Points
Points work in Threlte the same way they do in Three. Check three docs about Points and Point Material to learn more.
Ensuring Points Work Correctly with BufferGeometry
For your points to function correctly, it’s essential that they have an associated BufferGeometry with a specified attribute for point positions. Here’s a straightforward method using the default Threlte approach:
<T.Points>
<T.BufferGeometry>
<T.BufferAttribute
args={[positions, 3]}
attach={(parent, self) => {
parent.setAttribute('position', self)
return () => {
// cleanup function called when ref changes or the component unmounts
// https://threlte.xyz/docs/reference/core/t#attach
}
}}
/>
</T.BufferGeometry>
<T.PointsMaterial size={0.25} />
</T.Points>
In the case of <T.BufferAttribute>
, it is not enough to make it a child of <T.BufferGeometry>
. To actually link it,
you must invoke the attach method. If you skip this step, the attribute
won’t be associated with the geometry. Learn more about how attach works.
Alternatively, you can also define and manage BufferGeometry within <script>
tags or
in an external file. Once done, the <T>
component allows for direct attachment
to <T.Points>
, like so:
<T.Points>
<T is={pointsBufferGeometry} />
<T.PointsMaterial size={0.25} />
</T.Points>
Working code for this approach can be found in SceneAlternative.svelte
file of this example.