
A little sand island in the water, with a segmented palm tree, three coconuts, stones and tufts of grass. The wind bends the palm and stirs the leaves, waves roll out from the shore and the foam comes and goes; in the viewer you are the wind, with your pointer, and a click sends a gust.
What’s inside
- Mesh
- 206,442 vertices, 411,752 triangles
- Skeleton
- 46 bones
- Animation
brezza, 8 seconds, looping. A breeze that comes and goes: the palm bends and straightens up, the coconuts swing a moment later, the leaves flap with a wave running out to the tip, the grass trembles. On the water, waves roll from the shore out to sea and the foam spreads and pulls back. It loops seamlessly.- Parts
acquathe water, with the waves as shape keys (onda_1, onda_2, onda_3)schiumathe foam around the shore, with the risacca (backwash) shape keysabbiathe islandsassithe four stonestroncothe six-segment trunkcocchithe three coconutsfogliethe ten leavesciuffithe three tufts of grasstronco_1, …, tronco_4the trunk bones, from the sand to the topfoglia_1_1, …, foglia_10_3three bones per leaf, from the stem to the tipfilo_1, …, filo_10one bone per blade of grass
- Materials
- Acqua (bright blue, under a glossy clear coat), Schiuma (white with a hint of blue), Sabbia (warm sand, matte and velvety), Sassi (taupe grey, satin), Tronco (orange brown, satin), Cocchi (dark brown), Foglie (grass green, velvety), Erba (the green of the tufts)
- Weight
- 2 MB
How to use it
Load the GLB and start the animation. Every part is a named object, and you can bend the bones yourself too, after the mixer: that’s how you become the wind in the viewer.
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
// the model: meshopt-compressed, it needs its decoder
const loader = new GLTFLoader().setMeshoptDecoder(MeshoptDecoder);
const gltf = await loader.loadAsync('isola-con-la-palma.glb');
scene.add(gltf.scene);
// the "brezza" animation: 8 seconds, looping
const mixer = new THREE.AnimationMixer(gltf.scene);
mixer.clipAction(gltf.animations[0]).play();
// the bones: bend them yourself, on top of the animation
const osso = gltf.scene.getObjectByName('tronco_4');
// the light: a white studio, and white stays white
renderer.toneMapping = THREE.NoToneMapping;
scene.environment = new THREE.PMREMGenerator(renderer)
.fromScene(new RoomEnvironment(), 0.04).texture;
const clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
mixer.update(clock.getDelta());
osso.rotation.z += 0.08 * Math.sin(clock.elapsedTime * 2); // after the mixer: it wins over the clip
renderer.render(scene, camera);
});How it’s made
From drawing to shape
Before modelling, the first job was working out where the island was seen from: the edges of the water, the sand and the trunk in the drawing gave the camera’s height and lens, and every edge was mapped back onto the ground plan. Then the silhouettes of the model and the drawing were compared over and over, part by part, until they matched.
Truly smooth
Every piece is a mathematical surface: the sand is a soft union of ellipsoids, the water and the foam are slabs with rounded edges that follow the exact distance from the shore, the stones are pebbles bent by two slow waves. The mesh starts dense and is rebuilt with even triangles; every vertex is moved exactly onto the surface, with the normal taken from the surface itself. At the end every piece goes through a check: zero flipped triangles, zero open edges, zero doubled edges.
The leaves
Every leaf starts flat: an outline with V-shaped notches and a narrow stem, thick, with a rounded rim built ring by ring like a tube. Then it folds like a roof along the midrib, curves along its spine and twists a little; the normals go through the same fold, so the light stays exact on the curved leaf too. The ten leaves fan out from inside the heart of the crown, on three alternating levels: the stems come out already apart.
The trunk and the coconuts
The trunk is six stacked pots, as in the drawing: each has a rounded lip at the bottom that overhangs the segment below and narrows towards the top, and the joints run slightly crooked and stay crisp creases. At the top sits the heart of the crown, a smooth dome the leaves grow from; the three coconuts rest against it, each touching the trunk and its neighbours.
The wind and the waves
Forty-six bones: four for the trunk, one for the coconuts, three for each of the ten leaves, one for each blade of grass, plus the root. The breeze is written as functions of time that repeat every eight seconds, sampled at 24 frames per second. The waves are three shape keys shifted by a third of a cycle: weighted in turn they make a wave that starts at the shore and rolls out to sea, with each wave’s normals computed exactly. The shading between the parts is baked into the vertex colours.
Nothing touches
The leaves were placed by a program that nudges them by a few degrees until each one leaves room for the others, the coconuts and the trunk, while staying as close as possible to the drawing; the same for the blades of grass, which come out of the sand already apart and never dip back in, not even when the wind bends them. Then every frame of the breeze, and the viewer with its strongest gusts and the island turned every way, was checked triangle by triangle: nothing passes through anything else.