vidar.games

Voxel volumetric clouds

2026-10-31 · Discuss on X

Minecraft-style clouds, two ways. Same voxels, same Worley noise.
Left: a voxel turns solid once its density passes 0.
Right: each voxel is a bit of fog, lit by 8 samples marched toward the sun.

The problem

Volumetric clouds look soft because every sample is a little fog. Voxel games want hard edges. The quick fix is to threshold the density: a voxel above 0 becomes a solid block. That is the left half. You get the shape, but every block has the same flat shading, so a thick cloud core and a thin wisp look identical.

How it works

The right half keeps the volumetric lighting and only changes where the density is read.

  1. Every density lookup snaps to the centre of a 40 x 16 x 40 voxel.
  2. The view ray walks voxel by voxel with a DDA (Amanatides & Woo), so the voxel faces stay sharp.
  3. At each voxel, 8 light samples march toward the sun, also snapped to voxels, and Beer's law turns that into how much sunlight arrives.
  4. Front-to-back accumulation: transmittance *= exp(-density × step × 1.05), and the march stops once transmittance drops below 0.01.

The density itself is Sebastian Lague's: 3 tiled Worley layers per channel, shaped by a height gradient, eroded at the edges by a detail texture weighted by (1 - shape)³.

What I hit

At the repo values (densityMultiplier 0.82, densityOffset -3.64) the clouds came out thin and covered the whole sky once snapped to 40-unit voxels. I raised the multiplier to 12 and ran the offset from -5.6 to -5.0 over the clip. That ramp is the weather: coverage grows as you watch.

The repo walks fixed 11-unit steps. With voxels that blurred the faces, so I replaced the step loop with the DDA.

My build

three.js 0.170. Worley textures generated on the CPU from the repo's compute shader logic (64³ shape, 32³ detail). Clouds render at 640x360 and composite over a 2560x1440 voxel terrain with water, shadows, bloom and ACES. Animation runs 6x faster than the repo speeds as a time-lapse.

Trade-offs

When to use it

Block-style worlds that want clouds matching the terrain grid but still lit like volumes. For a fully smooth sky, drop the snapping and use the repo as-is.

New breakdowns go out on X first: @vidar_0208. If this one helped, you can buy me a coffee.

Source and credits

Repo: github.com/SebLague/Clouds (MIT license)

Code: I ported the cloud raymarcher from Clouds.shader (rayBoxDst, sampleDensity, lightmarch, the 2-lobe Henyey-Greenstein phase) to GLSL, and the Worley noise generator from NoiseGenCompute.compute to JavaScript, using the repo's "Flight Demo" settings. Changes: listed in notes (density snapped to voxels, voxel-by-voxel ray walk, higher density multiplier, smaller noise textures). The terrain, sky, water and the opaque-voxel comparison are my own. No assets or screenshots from the repo.

Topic inspired by @cazfps1's CazToon shader posts. No CazToon code or assets were used.