Blend texture seam between 2 terrains tiles

At the root of this problem is that i cannot for the life of me fathom how to paint a texture onto a terrain via script, the way of editing splatmap data just seems totally counter intuitive to me, rendering me unable to adapt the examples ive seen elsewhere to my situation. In short i am thick.

What im attempting to do is get from this:


To this:


Or similar. I can sample a point on Terrain 1 and retrieve the texture no problem. Where i fail miserably is painting it at a target point with a brush effect on Terrain 2. The closest i have got to this is wiping the whole terrain splatmap and turning it black!

So then to anyone more cranially endowed than myself, how do i stamp my retrieved texture using a stencil brush at my target position, assuming all have already been predefined?

To start, each terrain should use the same alphamap, i.e., under textures for each terrain you should see your dirt texture and then your grass texture. Make sure the order the textures appear is the same, or else it will make this next bit not work.

Next, you can store the terrain data for each terrain. This assumes you have some variables storing each terrain, which we’ll call terrain1 and terrain2. So do:

var data1 : TerrainData = terrain1.terrainData; 
var data2 : TerrainData = terrain2.terrainData;

Now get the alphamapWidth and Height. Note that each terrain’s width/height should be the same, or else none of this will work. This means we only need data1’s (or twos if you want) height/width.

var width : int = data1.alphamapWidth;
var height : int = data1.alphamapHeight;

Now we need to actually get the alpha maps of each terrain:

var map1 : float[,,] = data1.GetAlphamaps(0,0,width,height);
var map2 : float[,,] = data2.GetAlphamaps(0,0,width,height);

Now that you have the alphamaps, you want to adjust the maps to blend them together. Now, unfortunately you will not be able to achieve exactly what you outlined in the pictures above. In order for the terrains to blend along the edges properly, each neighboring spot on each terrain’s alphamap must be the same, so you cannot have dirt on the edge of terrain 1 and dirt/grass on the edge of terrain2. You have to have dirt/grass on the edge of both. The transition should look the same as what you outlined, it will just happen on the edge, rather than to the right of the edge.

What you can do is traverse the edge, finding the average between the two edges splatmap, and replacing these spots with this average. Something like this (Note, this code assumes terrain 1 is sitting to the left of terrain 2. If terrain 1 is below terrain 2 you will have to adjust the code a bit):

var num_of_splats : int = data1.splatPrototypes.Length;

var avg : float;
var i : int;
var y : int;
for(y = 0; y < height; y++)
   for(i = 0; i < num_of_splats; i++)
      avg = (map1[y,width-1,i] + map2[y,0,i])/2f;
      map1[y,width-1,i] = avg;
      map2[y,0,i] = avg;

This will traverse the edge from bottom to top. y will run from 0 to height-1. The width-1 defines the column of the alphamap we want to use of terrain 1. Since we are concerned with the right most column of terrain 1, this is why we use width -1. Since we are concerned with the left most column of terrain 2, we use 0 for map2 (map2[y,0,i]).

The i for loop iterates through each splatmap at each point on the alphamap.

Good luck!