How to solve seams in tiles due to normals?

I finally solved a problem that had been plaguing me where the splat maps had glaring discontinuous seams of data from ‘elsewhere’. Turns out my tiles were slightly misaligned in the world causing the glsl to behave oddly on the edges, wrapping splat data from the other edge of the tile.

Now I still have subtle (or not) seams between tiles both in the water layer (which includes snow) and terrain layer presumeably because the normal calculated at the edge vertices don’t account for their neighboring vertices in the neighboring tile. How would I fix these normals to match? I have access to the neighbor data but would have to manually calculate the normal. Is cge or x3d computing the normals somewhere? (TIndexedTriangleSetNode)

I have partially answered my question. It looks like I need to initialize Triangles.Normal to TNormalNode with a normal for each vertex.
I set all to vector3(0,1,0) and the seams go away, as does the shading since it is all same direction. How is the normal calculated when Normal is not set? I would like to be able to use the default for all non edge vertices and then average with corresponding vertex from neighboring tile for edge vertices (these vertices are the same location).

I modelled my GetNormal from yours getting the heights bilerped direct from underlaying data array… and voila, no seams, at least in the snow. Now the only visible seams between tiles are because the splat layer doesn’t blur between tiles.

Almost seamless looks sooo much better. Thanks for all the help! The solution was of course your code in TCastleTerrain. (The line on the hill isn’t a seam but a stream flowing straight down that very straight hill.)

I see you solved this already. Indeed, if you make terrain from multiple meshes, you need to provide explicit normal calculation to have continuous normals when one mesh is a “visual continuation” of another mesh.

For completeness, you asked how the normals are automatically calculated – this follows X3D spec of the respective nodes. See X3D, X3D Rendering component that includes IndexedTriangleFaceSet and finally X3D spec about IndexedTriangleSet :

If the normal field is not supplied, normals shall be generated as follows:

  • If normalPerVertex is TRUE, the normal at each vertex shall be the average of the normals for all triangles that share that vertex.
  • If normalPerVertex is FALSE, the normal at each vertex shall be perpendicular to the face for that triangle.

It indeed doesn’t account for “neighbor” meshes, since it doesn’t have any idea you may want to have the 2 meshes “visually continuous”.

1 Like