Procedural Splats
Forge makes it easy to create Gaussian splat collections procedurally, and includes some splat constructors that may be useful for tasks like creating a grid or text made of splats. The example "Procedural Splats" puts some of these to use in a scene.
Adding splats to a collection
To create a PackedSplats with custom, procedurally-derived splats use the methods pushSplat or setSplat:
The array in PackedSplats will be resized automatically to fit any splats you add. Alternatively, you can use the construct initializer callback:
Once you've created your PackedSplats, render it to the scene via a SplatMesh:
Alternatively, you can create the SplatMesh and its splats in the initializer, which internally passes your constructor to its contained PackedSplats:
Grid
Required parameters
| Parameter |
Description |
splats |
PackedSplats object to add splats to |
extents |
min and max box extents of the grid |
Optional parameters
| Parameter |
Default |
Description |
stepSize |
1 |
step size along each grid axis |
pointRadius |
0.01 |
spherical radius of each Gsplat |
pointShadowScale |
2.0 |
relative size of the "shadow copy" of each Gsplat placed behind it |
opacity |
1.0 |
Gsplat opacity |
color |
RGB-modulated grid |
Gsplat color (THREE.Color) or function to set color for position: ((THREE.Color, THREE.Vector3) => void) |
XYZ axis
Required parameters
| Parameter |
Description |
splats |
PackedSplats object to add splats to |
Optional parameters
| Parameter |
Default |
Description |
scale |
0.25 |
scale (Gsplat scale along axis) |
axisRadius |
0.0075 |
radius of the axes (Gsplat scale orthogonal to axis) |
axisShadowScale |
2.0 |
relative size of the "shadow copy" of each Gsplat placed behind it |
origins |
[new THREE.Vector3()] |
origins of the axes (default single axis at origin) |
Gsplat sphere
Required parameters
| Parameter |
Description |
splats |
PackedSplats object to add splats to |
Optional parameters
| Parameter |
Default |
Description |
origin |
new THREE.Vector3() |
center of the sphere (default: origin) |
radius |
1.0 |
radius of the sphere |
maxDepth |
3 |
maximum depth of recursion for subdividing the sphere. Warning: Gsplat count grows exponentially with depth |
filter |
null |
filter function to apply to each point, for example to select points in a certain direction or other function ((THREE.Vector3) => boolean) |
pointRadius |
0.02 |
radius of each oriented Gsplat |
pointThickness |
0.001 |
flatness of each oriented Gsplat |
color |
new THREE.Color(1, 1, 1) |
color of each Gsplat (THREE.Color) or function to set color for point: ((THREE.Color, THREE.Vector3) => void) |
Rasterizing Text
Required parameters
| Parameter |
Description |
text |
text string to display |
Optional parameters
| Parameter |
Default |
Description |
font |
"Arial" |
browser font to render text with |
fontSize |
32 |
font size in pixels/Gsplats |
color |
new THREE.Color(1, 1, 1) |
SplatMesh.recolor tint assuming white Gsplats |
rgb |
new THREE.Color(1, 1, 1) |
Individual Gsplat color |
dotRadius |
0.8 |
Gsplat radius (0.8 covers 1-unit spacing well) |
textAlign |
"start" |
text alignment: "left", "center", "right", "start", "end" |
lineHeight |
1.0 |
line spacing multiplier, lines delimited by "\n" |
Turning images into Gsplats
Required parameters
| Parameter |
Description |
url |
URL of the image to convert to splats (example: url: "./image.png") |
Optional parameters
| Parameter |
Default |
Description |
dotRadius |
0.8 |
Radius of each Gsplat, default covers 1-unit spacing well |
subXY |
1 |
Subsampling factor for the image. Higher values reduce resolution, for example 2 will halve the width and height by averaging |
forEachSplat |
undefined |
Optional callback function to modify each Gsplat before it's added. Return null to skip adding the Gsplat, or a number to set the opacity and add the Gsplat with parameter values in the objects center, rgba etc. were passed into the forEachSplat callback. Ending the callback in return opacity; will retain the original opacity. |
Example
Particle Effects
Some of the building blocks are meant to serve as "code inspiration", showing how a particle effect animation can be achieved using a "stateless" dyno computation graph that uses only the Gsplat index input to produce pseudo-random numbers that drive various randomized particle effects.
Note that Gsplat sorting takes a little bit of time and can "lag behind" the Gsplat updates each frame, so it's important that there is a reasonably stable correspondence between each frame's Gsplat output for the same index.
In staticBox, the AABB is sliced up into a 3D grid of cells, and random X/Y/Z points within those cells are sampled each frame, retaining consistency in Gsplat position between successive frames. See examples/gsplat-sweets-garden/main.js for an example that creates a staticBox.
Similarly, snowBox produces Gsplat trajectories that move in a deterministic fashion over time, with high similarity between adjacent frames. See examples/atmospheric/main.js for an example that creates a snowBox.
A snowBox instance has a collection of properties that can be tuned to achieve different particle effects. DEFAULT_SNOW and DEFAULT_RAIN are example parameter sets that look a lot like snow and rain, and can be used as a starting point for further tweaking: const mySnow = { ...DEFAULT_SNOW, density: 500 };
| Parameter |
Default Value |
Description |
box |
new THREE.Box3(new THREE.Vector3(-1, -1, -1), new THREE.Vector3(1, 1, 1)) |
min and max box extents of the snowBox |
minY |
Number.NEGATIVE_INFINITY |
minimum y-coordinate to clamp particle position, which can be used to fake hitting a ground plane and lingering there for a bit |
numSplats |
calculated from box and density |
number of Gsplats to generate |
density |
100 |
density of Gsplats per unit volume |
anisoScale |
new THREE.Vector3(1, 1, 1) |
The xyz anisotropic scale of the Gsplat, which can be used for example to elongate rain particles |
minScale |
0.001 |
Minimum Gsplat particle scale |
maxScale |
0.005 |
Maximum Gsplat particle scale |
fallDirection |
new THREE.Vector3(0, -1, 0) |
The average direction of fall |
fallVelocity |
0.02 |
The average speed of the fall (multiplied with fallDirection) |
wanderScale |
0.01 |
The world scale of wandering overlay motion |
wanderVariance |
2 |
Controls how uniformly the particles wander in sync, more variance means more randomness in the motion |
color1 |
new THREE.Color(1, 1, 1) |
Color 1 of the two colors interpolated between |
color2 |
new THREE.Color(0.5, 0.5, 1) |
Color 2 of the two colors interpolated between |
opacity |
1 |
The base opacity of the Gsplats |
onFrame |
undefined |
Optional callback function to call each frame |