Weird results after Procedural Terrain Splatmapping
Hi all,
I am currently working on assigning different textures to a terrain based on their height value. I use the awesome work from https://alastaira.wordpress.com/2013/11/14/procedural-terrain-splatmapping/ as a reference for this. This works quit well at this point but it does not seem to be consistent.
In the above image the left hand side of the pillar like terrain (red circle) has the correct textures assigned but the right hand side is way off and I can't find why.
Below is the code handling the texture assignment:
Dictionary<HeatmapLayers, float> heatmapColorThreshold = new Dictionary<HeatmapLayers, float>();
heatmapColorThreshold.Add(HeatmapLayers.DarkBlue, 0.165f);
heatmapColorThreshold.Add(HeatmapLayers.LightBlue, 0.33f);
heatmapColorThreshold.Add(HeatmapLayers.Green, 0.495f);
heatmapColorThreshold.Add(HeatmapLayers.Yellow, 0.66f);
heatmapColorThreshold.Add(HeatmapLayers.Orange, 0.825f);
heatmapColorThreshold.Add(HeatmapLayers.Red, 1f);
//init Terrain
GameObject terrainObj = new GameObject("TerrainObj");
TerrainData terrainData = new TerrainData();
terrainData.size = new Vector3(0.5f,2f,0.5f);
terrainData.heightmapResolution = 128;
terrainData.baseMapResolution = 128;
terrainData.SetDetailResolution(32, 16);
/**
add terrain collider and so on
big loop setting the heights
adding textures to terrain
**/
//set alphamap to same size as terrainHeightsMap, makes fiddling with the heights easier
terrainData.alphamapResolution = 128;
float[,,] splatmapData = new float[terrainData.alphamapWidth, terrainData.alphamapHeight, terrainData.alphamapLayers];
//iterate through alphamap
for (int y = 0; y < terrainData.alphamapHeight; y++) {
for (int x = 0; x < terrainData.alphamapWidth; x++) {
//get height from terrain height data which was filled earlier
float height = terrainHeightsArray[x, y];
float[] splatWeights = new float[terrainData.alphamapLayers];
//if height > orange threshold make it red
if (height > heatmapColorThreshold[HeatmapLayers.Orange]) {
splatWeights[5] = 1f;
//if height > yellow threshold make it orange and so on
} else if (height > heatmapColorThreshold[HeatmapLayers.Yellow]) {
splatWeights[4] = 1f;
} else if (height > heatmapColorThreshold[HeatmapLayers.Green]) {
splatWeights[3] = 1f;
} else if (height > heatmapColorThreshold[HeatmapLayers.LightBlue]) {
splatWeights[2] = 1f;
} else if (height > heatmapColorThreshold[HeatmapLayers.DarkBlue]) {
splatWeights[1] = 1f;
} else {
splatWeights[0] = 1f;
}
// Sum of all textures weights must add to 1, so calculate normalization factor from sum of weights
float z = splatWeights.Sum();
// Loop through each terrain texture
for (int i = 0; i < terrainData.alphamapLayers; i++) {
// Normalize so that sum of all texture weights = 1
splatWeights[i] /= z;
// Assign this point to the splatmap array
splatmapData[x, y, i] = splatWeights[i];
}
}
}
// Finally assign the new splatmap to the terrainData:
terrainData.SetAlphamaps(0, 0, splatmapData);
I am very thankful for any kind of advice helping me finding my error.
Your answer
Follow this Question
Related Questions
Terrain Layers cannot be populated at the same time as the splats 3 Answers
Texture color difference between terrain tiles,Texture seam between terrain tile group 0 Answers
Handling large format textures (7.1Gb .TIFF) in unity 0 Answers
Fast way to texture a 10km map? 1 Answer
How to modify a Terrain at runtime and get back to original Terrain on exit? 2 Answers