examples

76 interactive examples

hover example to preview

1

Snake 3D

audio
2

Creating Yoyo Animation

3

Creating Wooden Planks Animation

4

Creating Windstorm Animation

5

Creating Windmill Animation

6

Creating Whale Animation

7

Creating Waterfall Animation

8

Creating Volcano Animation

9

Creating Vaporwave Animation

10

Creating Tree Animation

11

Creating Tornado Animation

12

Creating Sun Animation

13

Creating Stone Wall Animation

14

Creating Spring Animation

15

Creating Spider Animation

16

Creating Spaceship Animation

17

Creating Solar System Educational Animation

18

Creating Solar System Animation

19

Creating Snowglobe Animation

20

Creating Snake Animation

21

Creating Sailboat Animation

22

Creating Robot Animation

23

Creating River Rapids Animation

24

Creating Rainbow Animation

25

Creating Prism Animation

26

Creating Pinwheel Animation

27

Creating Pine Tree Animation

28

Creating Phoenix Animation

29

Creating Pendulum Animation

30

Creating Octopus Animation

31

Creating Mushroom Animation

32

Creating Metronome Animation

33

Creating Meteor Animation

34

Creating Metal Plates Animation

35

Creating Lissajous Animation

36

Creating Lightning Animation

37

Creating Lighthouse Animation

38

Creating Lava Lamp Animation

39

Creating Lantern Animation

40

Creating Kite Animation

41

Creating Kaleidoscope Animation

42

Creating Jellyfish Animation

43

Creating Inner Planets Orbit Animation

44

Creating Hourglass Animation

45

Creating Hive Animation

46

Creating Grass Animation

47

Creating Geyser Animation

48

Creating Gear Animation

49

Creating Fountain Animation

50

Creating Flower Animation

51

Creating Fish Animation

52

Creating Fireworks Animation

53

Creating Fern Animation

54

Creating Earth Orbit Animation

55

Creating Dragon Animation

56

Creating Disco Ball Animation

57

Creating Demon Animation

58

Creating Crystallization Animation

59

Creating Crystal Animation

60

Creating Cosmic Formation Animation

61

Creating Coral Reef Animation

62

Creating Compass Animation

63

Creating Cloud Animation

64

Creating Clock Animation

65

Creating Castle Animation

66

Creating Carousel Animation

67

Creating Candle Animation

68

Creating Campfire Animation

69

Creating Cactus Animation

70

Creating Butterfly Animation

71

Creating Bush Animation

72

Creating Brick Wall Animation

73

Creating Blackhole Animation

74

Creating Beehive Animation

75

Creating Aurora Animation

76

🎈 Floating Balloons

hover for preview

Creating Snowglobe Animation

published on 8/21/2025
interactive example

Snowglobe Animation Tutorial

This guide walks you through how to generate a looping 3D voxel animation of a snowglobe using SpatialStudio. The script creates a magical winter scene with falling snow particles inside a transparent globe, then saves the animation to a .splv file.


What this script does

  • Creates a 3D scene of size 128×128×128
  • Builds a transparent spherical globe with:
    • A solid base platform
    • Curved glass walls with subtle reflections
    • A winter scene inside with trees and ground
  • Animates 200+ snow particles falling and swirling for 10 seconds at 30 FPS
  • Snow particles reset to the top when they hit the ground, creating an endless snowfall
  • Outputs the file snowglobe.splv that you can play in your viewer

How it works (simplified)

  1. Voxel volume Each frame is a 3D grid filled with RGBA values (SIZE × SIZE × SIZE × 4).

  2. Globe structure A sphere is carved out using distance calculations, with different materials for the base and glass dome.

  3. Snow particles Each snowflake has its own position, velocity, and swirl pattern that updates every frame.

  4. Winter scene Simple geometric trees and snowy ground are placed inside the globe as static decorations.

  5. Glass effect The globe walls use semi-transparent voxels with subtle blue tinting to simulate glass.

  6. Animation loop Snow positions are calculated using physics simulation, with particles recycling when they reach the bottom.

  7. Encoding Frames are passed into splv.Encoder, which writes them into the .splv video file.


Try it yourself

Install requirements first:

pip install spatialstudio numpy tqdm

Then copy this script into snowglobe.py and run:

python snowglobe.py

Full Script

import numpy as np
from spatialstudio import splv
from tqdm import tqdm
import random

# Scene setup
SIZE, FPS, SECONDS = 128, 30, 10
FRAMES = FPS * SECONDS
CENTER_X = CENTER_Y = CENTER_Z = SIZE // 2
OUT_PATH = "../outputs/snowglobe.splv"

# Snowglobe settings
GLOBE_RADIUS = 45
BASE_HEIGHT = 15
SNOW_COUNT = 250
TREE_COUNT = 4

class SnowParticle:
    def __init__(self):
        self.reset_position()
        self.vx = random.uniform(-0.3, 0.3)
        self.vy = random.uniform(-0.8, -1.2)
        self.vz = random.uniform(-0.3, 0.3)
        self.swirl_phase = random.uniform(0, 2*np.pi)
        
    def reset_position(self):
        angle = random.uniform(0, 2*np.pi)
        radius = random.uniform(0, GLOBE_RADIUS * 0.8)
        self.x = CENTER_X + radius * np.cos(angle)
        self.y = CENTER_Y + GLOBE_RADIUS * 0.8
        self.z = CENTER_Z + radius * np.sin(angle)

    def update(self, t):
        # Add swirling motion
        swirl_strength = 0.5
        self.x += self.vx + swirl_strength * np.sin(t + self.swirl_phase)
        self.y += self.vy
        self.z += self.vz + swirl_strength * np.cos(t + self.swirl_phase)
        
        # Reset if particle hits the ground or leaves the globe
        ground_level = CENTER_Y - GLOBE_RADIUS + BASE_HEIGHT + 5
        distance_from_center = np.sqrt((self.x - CENTER_X)**2 + (self.z - CENTER_Z)**2)
        
        if self.y < ground_level or distance_from_center > GLOBE_RADIUS * 0.9:
            self.reset_position()

# Initialize snow particles
snow_particles = [SnowParticle() for _ in range(SNOW_COUNT)]

def add_voxel(volume, x, y, z, color, alpha=255):
    if 0 <= x < SIZE and 0 <= y < SIZE and 0 <= z < SIZE:
        volume[x, y, z, :3] = color
        volume[x, y, z, 3] = alpha

def is_inside_sphere(x, y, z, cx, cy, cz, radius):
    return (x-cx)**2 + (y-cy)**2 + (z-cz)**2 <= radius**2

def generate_globe_structure(volume):
    # Generate base
    base_color = (101, 67, 33)  # Brown wood
    for x in range(SIZE):
        for y in range(SIZE):
            for z in range(SIZE):
                if is_inside_sphere(x, y, z, CENTER_X, CENTER_Y, CENTER_Z, GLOBE_RADIUS):
                    if y <= CENTER_Y - GLOBE_RADIUS + BASE_HEIGHT:
                        add_voxel(volume, x, y, z, base_color)
    
    # Generate glass dome (hollow sphere)
    glass_color = (200, 230, 255)  # Light blue glass
    for x in range(SIZE):
        for y in range(SIZE):
            for z in range(SIZE):
                if y > CENTER_Y - GLOBE_RADIUS + BASE_HEIGHT:
                    dist_to_center = np.sqrt((x-CENTER_X)**2 + (y-CENTER_Y)**2 + (z-CENTER_Z)**2)
                    if GLOBE_RADIUS - 2 <= dist_to_center <= GLOBE_RADIUS:
                        add_voxel(volume, x, y, z, glass_color, alpha=80)

def generate_winter_scene(volume):
    # Snow ground inside globe
    snow_color = (255, 255, 255)
    ground_level = CENTER_Y - GLOBE_RADIUS + BASE_HEIGHT
    
    for x in range(CENTER_X - 35, CENTER_X + 35):
        for z in range(CENTER_Z - 35, CENTER_Z + 35):
            if is_inside_sphere(x, ground_level, z, CENTER_X, CENTER_Y, CENTER_Z, GLOBE_RADIUS - 3):
                for y in range(ground_level, ground_level + 3):
                    add_voxel(volume, x, y, z, snow_color)
    
    # Generate simple trees
    tree_positions = [
        (CENTER_X - 20, CENTER_Z - 15),
        (CENTER_X + 15, CENTER_Z - 20),
        (CENTER_X - 10, CENTER_Z + 18),
        (CENTER_X + 25, CENTER_Z + 10)
    ]
    
    trunk_color = (101, 67, 33)
    leaves_color = (34, 139, 34)
    
    for tx, tz in tree_positions:
        if is_inside_sphere(tx, ground_level, tz, CENTER_X, CENTER_Y, CENTER_Z, GLOBE_RADIUS - 5):
            # Tree trunk
            for y in range(ground_level + 3, ground_level + 12):
                add_voxel(volume, tx, y, tz, trunk_color)
                add_voxel(volume, tx + 1, y, tz, trunk_color)
            
            # Tree crown
            crown_y = ground_level + 15
            for dx in range(-4, 5):
                for dy in range(-3, 4):
                    for dz in range(-4, 5):
                        if dx*dx + dy*dy + dz*dz <= 16:
                            crown_x, crown_z = tx + dx, tz + dz
                            if is_inside_sphere(crown_x, crown_y + dy, crown_z, CENTER_X, CENTER_Y, CENTER_Z, GLOBE_RADIUS - 3):
                                add_voxel(volume, crown_x, crown_y + dy, crown_z, leaves_color)

def generate_snow_particles(volume, t):
    snow_color = (255, 255, 255)
    
    # Update and render each snow particle
    for particle in snow_particles:
        particle.update(t * 0.1)
        
        # Render particle as a small cluster
        px, py, pz = int(particle.x), int(particle.y), int(particle.z)
        add_voxel(volume, px, py, pz, snow_color)
        
        # Add some particles with slight variations for depth
        if random.random() < 0.3:
            add_voxel(volume, px + 1, py, pz, snow_color)
        if random.random() < 0.3:
            add_voxel(volume, px, py, pz + 1, snow_color)

def generate_reflections(volume, t):
    # Add subtle moving reflections on the glass
    reflection_color = (255, 255, 255)
    reflection_intensity = int(50 + 30 * np.sin(t * 0.5))
    
    for i in range(3):
        angle = t * 0.3 + i * 2 * np.pi / 3
        rx = CENTER_X + int((GLOBE_RADIUS - 3) * np.cos(angle))
        ry = CENTER_Y + int(15 * np.sin(t * 0.4 + i))
        rz = CENTER_Z + int((GLOBE_RADIUS - 3) * np.sin(angle))
        
        for dx in range(-1, 2):
            for dy in range(-2, 3):
                if 0 <= rx + dx < SIZE and 0 <= ry + dy < SIZE and 0 <= rz < SIZE:
                    add_voxel(volume, rx + dx, ry + dy, rz, reflection_color, alpha=reflection_intensity)

def generate_scene(volume, t):
    generate_globe_structure(volume)
    generate_winter_scene(volume)
    generate_snow_particles(volume, t)
    generate_reflections(volume, t)

enc = splv.Encoder(SIZE, SIZE, SIZE, framerate=FPS, outputPath=OUT_PATH, motionVectors="off")

for frame in tqdm(range(FRAMES), desc="Generating snowglobe"):
    volume = np.zeros((SIZE, SIZE, SIZE, 4), dtype=np.uint8)
    t = (frame / FRAMES) * 2*np.pi
    generate_scene(volume, t)
    enc.encode(splv.Frame(volume, lrAxis="x", udAxis="y", fbAxis="z"))

enc.finish()
print(f"Created {OUT_PATH}")

Next steps

  • Adjust SNOW_COUNT to make the snowfall heavier or lighter
  • Change GLOBE_RADIUS to create a larger or smaller snowglobe
  • Modify tree positions and colors for different winter scenes
  • Experiment with swirl_strength to change how the snow moves
  • Add more decorative elements like a snowman or holiday ornaments inside the globe