Tony Yiding Tian

tonyxtian.com

This portfolio, drawn live: a procedural planet, sea and sky in WebGL 2

WebGL 2, GLSL, TypeScript, React · Sep – Oct 2026

The site's night finale: the moon over a dark sea, its light in a path across the water

The portfolio is itself a rendering project. Everything behind the pages is drawn live by one full-screen GLSL fragment shader on WebGL 2: space, a planet and its clouds, the sea, and the sky by night and by day. There are no textures or models; all of it is procedural, from noise, a few spheres and light.

From orbit to the sea

A first visit opens in space over a planet, with a comet circling the cursor on a precessing Kepler orbit, its tail stretching with speed and bending with its path. Scrolling plays the descent: the camera pans onto the planet and falls toward it. The clouds sit nearer the camera than the ground and magnify faster, a parallax that makes the zoom read as a fall, and they thin away as the camera drops through them. Noise octaves are added fractionally as the zoom doubles, so the coastlines keep their detail without popping, and the sea rises during the fall so the camera always comes down over open water.

The opening: the planet from orbit, under the name
The opening, out in space, where the descent starts on a first visit.

One pass of waves

The sea is adapted from afl_ext's MIT-licensed Very fast procedural ocean: peaked sine waves, each dragging the water along for the next. The original raymarches the surface and differences its height for the normal. Here the view ray meets the water directly, and the slope is summed alongside the height in the same loop: 24 wave evaluations a pixel instead of hundreds. The water is a sphere the planet's size, which is what curves the horizon, and its normals flatten with distance so the far sea doesn't fizz with detail finer than its pixels. Fresnel reflection of the sky, light scattered up through the crests and an ACES tonemap finish it.

Night and day

The last stop, Contact, looks up from the sea to the horizon on a critically damped spring that sets off alongside the camera's glide over the water. Night has to fall before any sky comes into view, so its timing comes from the camera's own geometry: night is complete in 0.45 s, and the top of the screen clears the horizon only at 0.53 to 0.6 s, whatever the screen's shape. The moon is shaded as a sphere in screen space, with seas, craters, a soft terminator and a darkened rim, and its light on the water is its own disc mirrored in the waves that catch it.

The same view by day: the sun low over a bright sea, with clouds
By day, where the moon was. The switch in the bottom bar turns the sky round to it.

The theme switch turns a wheel of sky: the sun and the moon ride opposite ends of it, turning about the view's axis, so the moon sets on the right as the sun rises on the left, arcs over the top and settles in its place. The page's own colours are registered CSS custom properties, which fade in step with the sea.

Frame budget

Around the renderer

GitHub

[email protected] · LinkedIn · GitHub · Resume