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.
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.
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()
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>
)
}
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.
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).
three.js demoRain, 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
snowThunderstorms 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.

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.

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.

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
burnState 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.

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.
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.
three.js demoCheck the forecast.
Scrub time, call up a storm and start a fire in the live demo, or go straight to the API reference.