Pixel Art Snow That Piles Up, Gets Trampled and Melts in the Sun

Snow in Philadelphia Fiefdom has real depth, up to half a meter, and every spot keeps its own share of it. It lies on walkable ground as one surface you sink into, and on everything else that faces up as a cap only as thick as that thing can hold. A set of overhead maps decides where it can lie, where the wind scours it off and where it piles up. Boots and tires trench it, and when it thaws, the spots the sun reaches melt first and the last of it lies in the shade.
Last time I wrote about lighting the city at night, with nothing lit unless a real light reaches it. This post leans on the same idea in daylight: whether the sun reaches a patch of snow decides how long it lasts.
When does snow start to lie?
It comes down to the temperature. Below freezing, what falls is snow. Just round freezing it's sleet: smaller, quicker, greyer flakes that melt as they land. The ground follows the air about an hour behind, so the first flakes melt where they land and wet the street. Falling snow chills the ground fast, though: after a few seconds it starts to lie, slowly at first while the ground is still melting some of it, then at the full rate once it covers. Under lying snow the ground holds at freezing, the way it does under real snow.
The seasons set the cold. The game has a calendar of four, a game month each, and winter's air is colder under whatever the weather is doing, so a clear winter day is cold and snow comes round with the season.
The flakes are whole-pixel squares, 1x1 or 2x2, falling 1 to 1.6 m/s. An earlier flake was a 1.5-pixel quad, and as it moved it covered one, two or four pixels: about a fifth of them changed size every step. A flake that lands on lying snow shows as a short white glint. On bare ground it lies a moment and fades.
How does snow go from a dusting to a blanket?
This took the most attempts:
- Islands. The first version drew lying snow from soft noise, and each patch appeared whole once it was a centimetre deep. Snow popped in as islands next to bare ground.
- A scatter of pixels. Then all the cold ground took a dusting at once, single pixels salted over everything, filling in. Better, but it read as noise.
- Clumps. Now thin snow fills in as soft clumps a few hand-widths across that spread and join: specks, then clumps, then patches, covering by 10 cm.
- By the centimetre. The map behind it is redrawn in steps, and the snow jumped at each one. Now each spot's depth is its share of what's lying right now, so it grows every frame.
How deep does it get?
Half a meter at most. Earlier passes tried 0.4 m and then 0.9 m before I settled on a realistic half meter. That's deep enough to bury feet, wheels, the foot of walls and anything low: a crate or a low wall in a drift goes under, with the snow running over it.
The first attempt at depth didn't build any snow at all. The shader just turned anything low enough white, which painted the sides of curbs first and never stood up off the ground. It was replaced with real geometry, in two parts, which come below.
What decides where snow lies?
Maps made by cameras looking straight down at the world:
- The cover map is a height map of the topmost surface. Anything well below it is under something (an awning, a roof, an upper floor) and gets no snow. Lamp heads, cables and signal arms don't count as cover, so thin things overhead don't leave dry lines below.
- The ground map sees only what you can walk on: roads, pavements, stairs, floors. It's what the lying snow stands on, and it measures each texel's distance to the nearest edge, which is where the banks come from.
- The snow map remembers how deep the snow lies on every texel. As it snows, each spot takes its own share of what falls. As it thaws, each spot loses its own share of the melt.
The share is where the wind comes in. Snow comes in on a slant three times steeper than the rain's, because a flake is light and the wind takes it at once. So:
- Out in the wind it's scoured thin, and it's laid down deeper in the lee of whatever stands up, more the harder it blows.
- A building's lee gets extra. The eddies there drop more snow, the opposite of the rain.
- Walls turned into the snow are plastered with clumps. Walls turned away stay bare.
- Under a tree's crown the leaves hold most of it, and a bare winter tree carries snow along its limbs.
- On a warm spot like a steaming manhole, none lies.
- Under a parked car none falls, so a car that sat out a snowfall leaves its own bare patch when it drives off.
Each spot's share is taken from the 35 cm round it, and the snow settles toward its neighbors a little each step, so drifts and scours grade into each other instead of stepping. The game reads the same map back on the CPU, so a footstep's crunch and how fast you wade match the drift you're standing in.

How does the snow on the ground work?
The lying snow on walkable ground is a snow field: one grid of 10 cm cells over everything the view shows, standing on the ground map plus the snow's depth. Points beside a step slide to where their own surface ends, so the snow meets every ledge and wall, rounding down at a drop and banking against a rise.
It used to be two grids, a fine square round the middle and a coarse ring out to the edges. They drew drifts and edges differently, so patches popped as they changed hands and a line ran up the stairs. To test the fix I panned the view over lying snow and compared neighbouring frames: the worst frame's change dropped from 7,158 pixels to about 1,200.
What happens to snow on things that face up?
Everything else that faces up gets a snow cap: roofs, awnings, benches, barrels, lamp hoods, cables. Each is a mesh built from the thing's own upward faces, lifted by the lying depth up to what that surface's width can hold, and rounded off in a lip over every open edge. A lamp hood gets a dome, a bench slat a loaf, a cable a thin ridge.
That width came from a bug. Caps first measured an object's bounding box, and a cable slanting between two posts had a box meters wide, so it piled 0.4 m of snow on a wire. Now it's the real upward area over the object's longest reach.
Before
AfterWhy does snow pile up at the edges?
Real snow doesn't end in a clean sheet at a curb. So it rounds down toward curbs, walls and roof edges as a bank that meets the ground. It piles against walls, props and curb faces and deepest in corners, builds a ridge along the line under an eave, and thins away within a hand's width in under cover instead of stopping dead.
Drifts are drawn out along the wind the snow first fell in, and they keep that shape. When they followed the wind all through a snowfall, every drift on screen was re-laid at each step and the snow seemed to build up in jumps.
What happens when you walk or drive through it?
- Boot prints land where each foot really lands, turned the way it points, pressed deeper when running.
- Trenches. In deep snow a walker wades and ploughs a channel, heaping the snow it pushes aside along the edges.
- Pace. Deep snow slows everyone: a walk keeps about three-quarters of its pace and a run about 0.6 of its own. Under cover, full pace.
- Tires press continuous ruts. Where the snow is deeper than a truck's underbody (0.45 m), the strip between the wheels is shaved down to it.
- Filling in. Fresh snow refills a track with as much as it took out, so deep prints in deep snow last.
- Cars carry their own. Snow piles up on a parked car, blows off when it drives, and someone at the wheel has the wipers clear the windscreen stroke by stroke, leaving a line at the driver's pillar.
How do sun and shade change the snow?
This is the part I most wanted to get right. Three things decide how warm a patch of snow is:
- The time of day. The air is 7 °C colder at night than at midday, and by day the ground sits a couple of degrees above the air.
- The season. Winter's days are short and its sun is low.
- Whether the sun reaches it. For every texel of the snow map, the game traces a line toward the sun through the cover map. If nothing's in the way, that spot melts at 1.6 times the average. In a building's shadow it melts at 0.35 times. So a thaw clears the sunny side of the street first, and the last snow lies in strips along the shaded side and in the lee of walls.
This demo needs JavaScript.
The thaw itself goes by how warm it is: slowly just above zero, fast in a warm sun, faster in rain. The snow goes gray and slushy the whole way through. The meltwater keeps the ground soaked and fills the gutters and dips, which only drain once the snow is gone.

What about icicles and frost?
Icicles grow where water drips into freezing air. Roof snow melting in the sun or from the building's warmth runs to the cold edge and freezes there, and freezing rain and sleet feed them too. They grow best just below freezing. Too cold and nothing melts to feed them. Above freezing they melt, faster in the sun, and drip from their tips. Each one hangs off a lamp shade, a signal arm or an awning's edge, and is drawn a whole pixel at a time: a tapering column with a lit side, a shaded side and a bright tip.
Frost rimes what faces up on clear, freezing nights. A car left out ices over more than the ground does, because its thin glass loses its warmth to the sky. The feathery ice keeps into the morning until the sun melts it, or until someone gets in and the defroster clears it from the bottom up and the wipers sweep their arcs through it.
What does lit snow look like at night?
At night snow catches the town's skyglow and stays a pale lavender, the brightest thing in the dark, with lamps pooling warm on it. It was slate gray at first. Under a bright lamp it used to blow out to flat white, so its tone now rolls off just below white and keeps its shape. Its outline is a cool blue-gray instead of the near-black ink, which looked harsh round something white. One thing went: little dark specks under the lamps meant as falling snow's shadows. They popped in and out over every lamp's pool with nothing casting them.
How did I keep it fast?
- The snow field moves in chunks of 16 cells. Lamps light the snow, so every move redrew every nearby lamp's shadow, nearly every frame. Snow walking went from 6.8 to 6.1 ms with about 1,250 fewer draw calls.
- No stall turning the view. The field rebuilt its whole mesh for each new size during a turn: a run of 40 to 80 ms frames. Its size now steps in 2 m and only grows. Over 600 frames of turning, slow frames went from about 60 to 1 to 3.
- What never changes is baked once. How the snow piles against things and banks at edges used to be worked out at every vertex in every view and shadow pass. Now it's stored in the snow map once a texel: city snow on the GPU 6.24 to 6.0 ms.
- Caps baked with the city. Building them as chunks streamed in cost about 2 s of main thread for every 8 s of driving, with frames up to 80 ms. Now each chunk's caps are built ahead of time and loaded on a thread.
- Snow stays out of lamp shadows and reflections. It would multiply their cost, and nobody can see it there.
Quick answers
Is the snow just a white texture? No. It has real depth: you sink into it, tires rut it, the wind piles it, and it banks against curbs and walls.
Does it change how the game plays? Deep snow slows everyone down, and under cover you're back to full pace.
Does shade really keep snow longer? Yes. Each spot of snow checks whether the sun reaches it, and in shade it melts at under a quarter of the sunny rate.
Follow along
Philadelphia Fiefdom is a single-player sandbox I'm building in Godot, in a city laid out after Philadelphia: a mockup with its own invented streets for now. If you missed it, the last post was about lighting the city at night. Next is the city all this falls on: a Philadelphia-shaped mockup city. Next up: that Philadelphia-shaped mockup city. Join the playtest list to play it early, or come say hi on Discord (opens in a new tab).