Devlog

Forest where the map says forest, 100 km round

Published

At Low, 300 m over the ground, trees used to stop 10 km from the camera. Now they fill the whole area, 100 km in every direction from its centre, and they grow only where the ground is forest. The test area is the plain around Bangkok.

Before: trees in the wrong places

The ground’s colour comes from a satellite map with 500 m pixels. Its land types had been tuned for a brighter map, so the farmland round Bangkok was never recognised at all. Rainforest stood on the paddy plain, and trees grew in the shallow, muddy water of the Gulf of Thailand.

Blocks of dark rainforest standing on a flat yellow-green farming plain, seen from 300 m.
Before: rainforest blocks on the paddy plain.
Trees growing out of shallow blue coastal water.
Before: trees on shallow coastal water.

What changed

Dense dark forest in the foreground with open farmland beyond and treelines toward the horizon.
After: forest only where the ground is forest.
Open yellow-green farmland with no trees, a forest edge off to the right.
After: open farmland, no stray trees.

Clump cards

A forest seen from 300 m is mostly canopy, so we stopped drawing single trees. Each 100 m cell gets one card about 100 m wide showing a clump of trees, all the way up to the camera. (The tree models are placeholders; see credits.)

As the camera climbs, the clumps fade instead of switching off. They are fully shown up to 8 km above the ground, then thin out to nothing by 20 km. Switching them off at once at 8 km gave a visible pop. We tried fading out at 30 km instead, but seen from 25 km up the clumps then cost 1 to 3 ms per frame on the graphics card, so we settled on 20 km. At 20 km, the view from high up has no clumps and no cost.

From 10 km to the whole area

The first step was a 60 km draw range round the camera. On a laptop RTX 3070 at 1080p, the graphics card’s cost stayed flat at about 2.3 to 2.8 ms per frame from 10 km to 60 km. What cost time was the number of draw calls, which grows with the number of ground chunks. Making each chunk 10 km across instead of 2 km cut draw calls from about 1,955 to about 400, and the processor’s share of drawing from 6.0 ms to 2.2 ms at 60 km.

A circle round the camera still had an edge: from about 8 km up, you could see where the forest stopped. So the forest no longer follows the camera. Every 10 km chunk inside the area’s ring, 100 km round its centre, is drawn, fading out over the ring’s last 3 km. Round Bangkok that is 368 chunks and about 664,000 cards.

New forest no longer pops up either: a freshly built chunk fades in over half a second.

Four pairs of the same views side by side; the right-hand views show more treelines toward the horizon.
Draw range 20 km (left) and 60 km (right): more treelines toward the horizon.
Five copies of the same view stacked, with the forest reaching farther toward the horizon in each.
The horizon at 10, 20, 30, 40 and 60 km, top to bottom.

Baked forests

Working out what grows in every cell is slow, so it is done ahead of time. For each area the game saves what grows in each 100 m cell and the ground height there. That takes a few MB; saving the finished cards would have taken up to about 290 MB. In a 25 km test ring, the forest filled in 2.3 seconds from the baked data, against 31.6 seconds worked out live, with identical cards either way. The whole Bangkok area fills in about 23 seconds from the baked data, nearest chunks first. Areas without baked data still work: their trees fill in more slowly, with no cost to the frame rate.

The Bangkok bake covers the area plus 60 km round it: 880 chunks and 1.81 million cards, 3.5 MB, baked in about 4 minutes.

Related