Guides
Shelter and occlusion
A top-down depth map of your scene tells the weather what's overhead. Rain and snow stop at roofs and tree crowns, splashes land on top of them, and the ground underneath stays dry and free of snow.
snowfall at the well. The snow blanket stops under the well roof and the bench seats. The shelter edge is soft, and slanted with the wind.#Choose the occluders
weather.setOccluders([houses, trees, ground]); // these objects and their children
weather.setOccluders(village); // one object is fine too
weather.setOccluders(null); // every visible mesh in the scene (the default)The occluders must be part of the scene. Objects with userData.weatherOccluder = false are always skipped, and so are the weather's own meshes. setOccluders() re-renders the map straight away.
#What it affects
| Rain and snow | Drops and flakes below the map's surface are culled |
| Splashes | Spawn on the top surface: roofs, benches and walls as well as the ground |
| Patched materials | Surfaces with something above them stay dry, puddle-free and snow-free |
For surfaces, the shelter test takes several taps in a ring around the pixel. The ring is slanted with the wind, so the dry patch under a roof shifts downwind in a gale. The tap count comes from the quality tier's shelterTaps: 4 on low up to 12 on ultra (0 would turn shelter off). Small covers such as lamp caps and window sills keep almost nothing dry, and tall covers such as tree crowns let some weather through.
#The map
weather.occlusion is an OcclusionMap. By default it covers an 80 m square at 512², centred near the camera.
const weather = await WeatherSystem.create({
renderer, scene, camera,
occlusion: { size: 120, resolution: 1024, follow: true, floor: 0 },
});| Option | Default | |
|---|---|---|
size | 80 | Side of the covered square, in metres |
resolution | 512 | Texels per side |
follow | true | Re-centre on the camera |
floor | 0 | Height used where nothing was drawn, and outside the map |
OcclusionMap also takes top (40 m, the ortho camera's height above the centre) and depth (60 m, its depth range) when you construct it yourself.
#When it re-renders
The map is not redrawn every frame. It re-renders when:
- you call
setOccluders(), - you set
weather.occlusion.needsUpdate = true, - or, with
follow, the camera leaves the middle 40 % of the map. It then snaps to a grid ofsize / 10, which is 8 m for the default map.
door.rotation.y = open ? 1.4 : 0;
weather.occlusion.needsUpdate = true; // moving occluders need a manual refresh#Excluding objects
lampGlow.userData.weatherOccluder = false; // never occludes, even inside an occluder group
weather.occlusion.exclude.add(myParticles); // same, as a setExclude anything transparent or airborne that shouldn't keep the rain off what's below it, such as your own particles, glows or a flag.