Chunked LoD cracks


I’m here to ask for help.
I have program for terrain editing, but I went into one problem I can’t solve. Between each chunk is crack, how to fix it? I tried google it but I don’t understand it.

I have 4x4 field with class MapChunk. Each chunk has own data for heightmap. I render one by one chunk.


And there is my bug result:

You can see on image red lines which mean end of chunk.

And now my question… How can I connect first chunk with second? To dissapear these cracks.
Also I want to note: I’m using 4 different textures per chunk.

My draw function for chunk looks like:

        // Render the quad as a patch
            Mesh.bind(); // bind Vertex Array Object
            Mesh.createAttributeArray(IMesh::Vertices, shader, "vertexPosition", GL_FLOAT, 0, 2); // IMesh::Vertices == 0


            world->getGLFunctions()->glDrawArrays(GL_PATCHES, 0, Mesh.getNumFaces()); // Mesh.getNumFaces() == 1600


First, let’s clear up that your approach is not a chunked LOD, because it is not a LOD scheme at all.
You have just divided your map into tiles. Are you using quadtree or calculate screen-error metric to choose a proper chunk?
I guess the answers to both questions are negative, so it is not a LOD scheme.

Let’s back to the question. In order to stitch tiles, you have to:

  • calculate the influence of the modeling transformation (extrusion or whatever you are doing with the vertices) to all neighboring tiles, and modified all vertices influenced by the transformation,
  • add skirts around the perimeter of the tiles if vertices on the edges do not correspond to each other.

Yes I divided map into tiles and then to chunks. I thought its called LoD. I’m not using quadtree, using screen-error.

I read something about skirts but I don’t know how to make them. Yesterday I tried to google these “skirts” but no success. So if you can show me some example how to add them I will be glad.


LOD stands for Level-Of-Detail. It serves to manage the complexity of the objects on the scene. I guess you have just a set of tiles which geometry doesn’t change as the viewer moves.

It is quite simple to add skirts. If your tile consists of n x n vertices, just make a tile of (n+2) x (n+2) vertices instead, and move down the vertices at the edge, such that they create a drape. But no skirts can seamlessly stitch adjacent tiles if you change the vertices at one side of the border and not on the other, as you’ve shown on the fig.2.

Okay so, if I have 40x40 vertices = 1600 patches I should have 42x42 vertices = 1764 patches.

My chunk heightmap is 256x256 (= 6,4 height values per patch). How this should work? If vertice is bigger than 40 then recalculate it somehow?

I don’t quite understand your math.
You need 257x257 vertices per heighmap chunk in order to divide it into equal tiles (2x2 tiles of 129x129 vertices, 4x4 tiles of 65x65 vertices, etc.). The vertices on the edges are shared between tiles.
If there are 4x4 tiles of 65x65 vertices, adding skirts results in 67x67 vertices, where vertex (1,1) corresponds to vertex (0,0) of the original tile. With skirts, not just a single row/column in each tile overlaps, but three. Of course, only a single row/column coincides.Others are lowered down.

Hm we don’t understand each other :smiley:

Whole map (4x4 chunks)

  • Width: 1024
  • Height: 1024
  • Number of patches: 25600 (160 per row/column)

One chunk

  • Width: 256
  • Height: 256
  • Number of patches: 1600 (40 per row/column)

I little describe my program architecture…

class World has 1 class of MapTile. MapTile owns 16 MapChunk classes. I don’t draw MapTile, only MapChunk.

MapChunk class:

  • float mapData[256 * 256] // height storage
  • Mesh contains patches (1600) and buffer with positionData for vertex
  • number of patches is calculated from “trianglesPerHeightSample * MAP_WIDTH / CHUNKS / maxTessellationLevel” (10 * 1024 / 4 / 64 == 40)

So I should have number of patches calculated: (trianglesPerHeightSample * MAP_WIDTH / CHUNKS / maxTessellationLevel) + 2

And should I increase MAP_WIDTH / CHUNKS (256) to 258?

It seems that I’m beginning to understand the problem. :wink:

You are using tessellation shaders to add details (you should mention that). The patch is actually a single height and a single vertex position (I don’t know why you need a position, but that’s probably because you don’t have equally spaced vertices). The patches are expanded to 10x10 vertex grid in TS. I’m not aware of what’s going on in TS, but let’s say it’s ok. When you modify a terrain, you actually modify the single vertex representing the patch on the CPU side. GPU moves the other 100 vertices produced by it, and you have no fine control over that. Are those assumptions correct?

I have no other advice at the moment but to add a single patch wide ring around each chunk (overlapping with adjacent chunks), and modify it when modifying neighbors. More details are required in order to make some better proposal, but adding an outer ring to stitch chunks sounds ok.

Oh, sorry about I didn’t mentioned tess. shader.

Yes you’re correct, I editing on CPU mapData and sending them to GPU. Yes I have no final control about mentioned vertices produced on GPU.

To your advice, add wide ring around chunk should be part of chunk rendering or not? Btw do you know how to fix texture flickering? 2 heightmaps on same height value.

I can add some video or source code?

Well, after reconsidering the problem, it seems it is easier to add a ring around chunk separately, although I’m implementing skirts as a part of blocks (but have totally different approach compared to yours, and using no TS).
Another approach would be to set tess. level to 12 (instead of 10) and lower down vertices at the edge of the chunk in tessellation evaluation shader.

Thanks for advice, I will try it and then post feedback.

Hi there,

So I made some stuff, but I still need advice.

I created class called MapCleft for solving these cracks. I define previous and next chunk… ex. for vertical > previous = left chunk, next = right chunk. I take last column and first column. My MapChunk is 256x256 so this MapCleft is 2x256

Explain image:
Without MapCleft:
With MapCleft:

It seems MapCleft is wrong calculated vertices or I dont know.

Vertices count for width: 10
Vertices count for height: 40

Using still tessellation for this stuff. Btw I’m using same shaders as for MapChunks the different is just MapCleft is width 2 and MapChunk is 256