17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 15:39:20 +02:00
Commit Graph

2 Commits

Author SHA1 Message Date
maj00r
9408216ae7 Give the terrain its own archive, its normals, and a level per tile
The tiles moved out of the scenery's pak into an archive of their own: a
sorted index of fixed-size entries found by where a tile sits in the
quadtree rather than by a name, each entry compressed on its own so a
tile can be read without touching the rest. A name apiece would have been
seventy megabytes of index to read before the first tile could be drawn.

An entry carries what its tile's ground asks for - how far it departs
from the finest mesh, and how long its triangles are - because which
level to draw has to be settled for tiles that are not on the card yet,
and the index is the only thing about them that is read up front. Until
now the figure came from the tile's level, which is the worst tile in it,
so one steep corner spoke for every tile that shared its level.

The mesh carries a normal per vertex, octahedron-encoded into two bytes,
in place of the face normal the fragment stage worked out from how the
view position changed across a triangle. A face normal makes the ground
read as facets, and a coarser level's facets face differently from the
ones they stand for, so the light over a hillside changed as the level
did. A geometry stage hands the fragment stage the three materials of the
triangle it is in and the barycentric weights, so ground changes over a
triangle rather than along its edge; 3.3 has no gl_BaryCoordEXT.

And the level a tile is drawn at now counts the camera's height. The
distance was measured on the ground plane alone, which puts the tile
underfoot nought metres away from a camera a kilometre above it - and
nought metres asks for the finest level there is, so a view from the air
wanted the whole ground at full detail, more tiles than the buffers hold,
and what would not fit came out as holes.

Archives written under the old rules are refused at the door and baked
again.
2026-09-20 21:22:03 +02:00
maj00r
d2a5f284e3 Draw terrain one call per level, from texture arrays, culled to the view
Each resident tile had a height texture and a material texture of its own, uploaded with
glTexImage2D, and was drawn once per material it held with every other material's
fragments discarded, all of them whether in view or not. Thousands of draws a frame.

Now the tiles of a level live in one pair of texture arrays (terrain_tile_pool), a layer
per tile. A pool starts at sixteen layers and doubles when full, copying what it holds on
the gpu, so a level takes only the memory its tiles need; uploads go through a pixel
buffer orphaned for each tile. The ground textures of every material are gathered into
one sRGB array with mipmaps (terrain_ground) - drawn into it layer by layer by a small
shader once the engine has each texture ready, since the scenery's textures are
compressed and cannot be blitted - with a table of placeholder colours and measured
tiling beside it.

Each frame the tiles in range are tested against the frustum by bounding sphere and
gathered per level into a buffer texture of instance data, and each level is drawn in
one instanced call. The fragment shader reads the four samples around it, drops the cell
when any of them carries no ground - exactly the rule the bake already assumed - and
blends the ground textures of their materials by distance, so material boundaries
follow the samples smoothly instead of stepping along triangle edges.

State the copy pass changes is captured and put back, and the texture unit cache is
reset after raw binds, so the rest of the renderer finds things as it left them.

On baltyk: all 30 materials land in the array, 663 of the 1120 tiles in range are drawn
after culling, and a frame is at most six terrain draws. The residency line in the log
now says how many tiles in range were drawn.
2026-09-17 16:28:43 +02:00