Yet Another Terrain Seams Question

Hello Everybody,

I've been playing around with Unity trying to create terrains at run-time. I've managed to make a terrain load from a socket connection providing heightmap information, and now I'm trying to make 2 terrains stitch together seamlessly.

I don't know if I took the best approach (correct me if I didn't), but I created 2 empty GameObjects in my scene named TerrainContainer1 and TerrainContainer2. In each of those, I added my script which will connect to my server, will request for the correct heightmap and will generate a terrain in run-time with the data the server sent to it. So far, it is doing pretty good. I placed a white pixel in each of both terrains' corners to check if I'm rendering everything and placed numbers in each corner to check if I'm joining the correct sides, and seems it does nicely.

Then, I read around that I should set the SetNeighbors so that each terrain points to each other to overcome LOD problems while doing seamless terrains. As when I play my "game" I don't have any terrain loaded, I created another empty GameObject and added a C# script to it with 2 static variables. In the update loop, I check if both terrains are already loaded, and if so, I set the neighbors only once (i placed a flag variable there so I don't setNeighbors every frame).

I also tried to set neighbors in every possible arrangement only to ensure that I'm setting them correctly, and placed some Debug.Log to see if the setNeighbor call happens AFTER the 2 terrains loading, and yes, it does.

Anyway, even doing all that, I still have a seam. Strangely enough, where my corner white pixels are, the terrain match nicely, but not in the rest of it.

To generate the heightmap, I made a 2050x1025 image in Photoshop, and cut 2 1025x1025 images from it, and saved as PNG non-interleaved, grayscale.

There is the image from when I run the app:

alt text

What I'm doing wrong? it is the fact each terrain resides within different GameObjects, so they can't setNeighbor each other? Any ideas? Did I take a nice approach in doing this, or my design is flawed?

Thanks in advance!

Have you tried changing the height maps from "repeat" to "clamp" wrap mode? That might be causing anomalies along the edges. Alternatively you can set a single sold height along all the edges to ensure a match on both sides and then you'll have to hide it somehow like with rocks and bushes or hills made to match the terrain.

Just some ideas as your system sounds pretty good, but just setting neighbours wont make the height the same on each terrain as you've seen.

Changing wrap mode didn’t helped me. So i wrote a script for fix it manually. It is pretty basic, but maybe it can help somebody. You can run it once, because all terrainData will saved automatically.

public static void Fix(Terrain cur, Terrain right, Terrain bottom)
    {


        float[,] newHeights = new float[resolution, resolution];
        float[,] rightHeights = new float[resolution, resolution], bottomHeights = new float[resolution, resolution];

        if (right != null)
        {
            rightHeights = right.terrainData.GetHeights(0, 0, resolution, resolution);
        }
        if (bottom != null)
        {
            bottomHeights = bottom.terrainData.GetHeights(0, 0, resolution, resolution);
        }

        if (right != null || bottom != null)
        {

            newHeights = cur.terrainData.GetHeights(0, 0, resolution, resolution);

            for (int i = 0; i < resolution; i++)
            {
                if (right != null)
                    newHeights[i, resolution - 1] = rightHeights[i, 0];

                if (bottom != null)
                    newHeights[0, i] = bottomHeights[resolution - 1, i];
            }
            cur.terrainData.SetHeights(0, 0, newHeights);
        }
    }