WebGPU · three.js · React Three Fiber

threejs-weathering: Weather that leaves a mark.

Fronts, rain, snow, gusts and thunderstorms over your world, wildfires that spread with fuel, wind and slope, and one material-state layer that makes everything wet, snowy, burnt or damaged. Scrub time backwards or forwards and the same seed always gives the same sky.

screenshot · weathering.html open ↗
A wildfire front burning through a conifer forest, smoke drifting downwind
4material states
24kraindrops, one draw call
22burnable fuel models
3draw calls per wildfire
Getting started

Weather in a few lines.

Give the weather a threejs-biomes world and a time. Rain, lightning and fire read it; a state field turns it into wet, snowy and burnt ground that any node material can wear.

three.jsthreejs-weathering
import { Weather, StateField, Precipitation, Lightning, Wildfire,
  applyMaterialStatesTo } from 'threejs-weathering'

const weather = new Weather({ seed: 'storm', wind: { speed: 9 } }, world)
const field = new StateField({ size: 1024 })
const rain = new Precipitation({ weather, camera })
const lightning = new Lightning({ weather, camera })
const fire = new Wildfire({ world, weather, field, size: 1024 })
scene.add(rain.object, lightning.object, fire.object)
applyMaterialStatesTo(terrain.material, { ...field.node(), heat: fire.node().heat })

// each frame
fire.update(time); rain.update(time); lightning.update(time)
field.updateFromWeather(weather, time); field.update()
React Three Fiberthreejs-weathering/react
import { Weather, Precipitation, Lightning, Wildfire } from 'threejs-weathering/react'

function Sky({ world }) {
  return (
    <Weather world={world} timeScale={60} field={{ size: 1024 }}>
      <Precipitation />
      <Lightning onStrike={(s) => console.log('strike', s.x, s.z)} />
      <Wildfire size={1024} ignitions={[[0, 0, 10, 4]]} />
    </Weather>
  )
}
Install npm i threejs-weathering threejs-biomes three Full API reference → React components →
What's in the box

Every kind of weather.

All of it is seeded and a pure function of time, so it scrubs, replays and matches across machines. Everything below runs in the demo.

01

Weather systems

Fronts that drift with the wind.

Cloud masses drift along the prevailing wind and change shape over hours. Cover, rain, wind, humidity and fog come from the world's climate at each point, so deserts stay dry, rainforests stay wet and mountains get snow. Ask for any place and time with weather.at(x, z, time).

Rain over a forested hill, with the sampled weather in the demo HUDthree.js demo
02

Rain, sleet and snow

Particles around the camera.

24,000 rain streaks and 16,000 snowflakes in one instanced draw call each, placed in the vertex shader. Density follows the rate, slant follows the wind, splash rings land on the ground, and temperature decides rain, sleet or snow.

Rain slanting in the wind through fog over a forestrain
Snow falling on snow-covered trees and groundsnow
03

Thunderstorms and lightning

Strikes you can look up in advance.

Storm cells grow and die with their own showers, outflow gusts and strike rates. weather.strikes() lists every strike in a box and time window, and Lightning draws them as branching, flickering bolts with a flash. Subscribe with onStrike for thunder.

A branching lightning bolt over a wet valley in the rain
04

Wildfires

Fuel, moisture, wind and slope.

A cellular fire after Rothermel: spread comes from grass, shrub and tree fuel read off the biome scatter tables, fuel moisture from recent rain, wind along the front and slope. Water, rock, snow, roads and firebreaks stop it, and lightning starts new fires.

A fire front with flames and smoke spreading through a conifer forest
05

Burn scars and regrowth

Grass in weeks, trees in decades.

Cells go unburnt, burning, burnt, regrowing. The scar is written into the state field, so ground and trees char where the fire passed. Grass returns in a month, shrubs in two years, forest in twenty, and regrown land can burn again.

A blackened burn scar across a hillside above unburnt forest
06

Wet, snowy, burnt, damaged

One material layer for everything.

Four states, each 0 to 1. applyMaterialStatesTo() adds them to any node material: wet darkens and glosses, with puddles and drip streaks; snow settles on upward faces; burn scorches, chars, strips leaves and glows; damage cracks and dents. Props, vehicles and fauna wear the same states.

  • wetness
  • snow
  • burn
  • damage
  • heat
  • puddles
  • drip streaks
  • sparkle
  • embers
  • cut-outs
Wet ground with puddles shining under a lightning flashwet
Glowing, scorched ground and leafless trees inside a fireburn
07

State fields and instances

A map of what happened where.

A StateField is a low-resolution world map of the four states that shaders and CPU code both read. It fills with wetness and snow from the weather on a time budget, and with scars from fire. InstanceStates gives each tree, rock or building its own.

Snow cover from the state field on hills and trees, the valley floor still clear
08

Storm damage

Gales that leave their mark.

StormDamage adds damage wherever gusts pass a threshold, tick by tick, so a gale leaves the same marks every time. applyDamage() does the same for impacts, explosions and falling trees.

THREEJS-WEATHERING
09

Made for React too

A <Weather> tree.

<Weather> owns the clock and the state field; <Precipitation>, <Lightning> and <Wildfire> drive themselves from it. useWeatherSample(x, z) reads the weather anywhere for your own UI.

The weathering sandbox with its control panel and weather HUD during a lightning flashthree.js demo

Check the forecast.

Scrub time, call up a storm and start a fire in the live demo, or go straight to the API reference.