- Home /
Normal maps using TerrainToolkit and Code?
How do I get the normal map textures that go along with the these 4 textures to be applied using the TerrainToolkit?
This is done procedurally, also it seems I can only use 4 textures, anymore and it fails thanks to incorrect value for heightstops. However that is not the main issue here as I want to know how to get the normal maps into the terrain the same way
Code:
float[] slopeStops = new float[2];
float[] heightStops = new float[4]; //This has to be same number as terrain textures.
slopeStops[0] = 0.1f;
slopeStops[1] = 25.0f;
heightStops[0] = Random.Range(0.01f,0.015f);
heightStops[1] = Random.Range(0.08f,0.58f);
heightStops[2] = Random.Range(0.37f,0.98f);
heightStops[3] = Random.Range(0.71f,1.0f);
this.gameObject.GetComponent<TerrainToolkit>().TextureTerrain(sStops, hStops, desertTextures01);
Answer by theness_ · Jun 09, 2015 at 06:26 AM
I was facing the same problem and wrote a quick hack to fix it by changing toolkit code. It's ugly, but it works :)
step 1, find the function addSplatPrototype() inside TerrainToolkit.cs and change it to this:
public void addSplatPrototype(Texture2D tex, Texture2D normal_tex, int index) {
SplatPrototype[] newSplatPrototypes = new SplatPrototype[index + 1];
for (int i = 0; i <= index; i++) {
newSplatPrototypes[i] = new SplatPrototype();
if (i == index) {
newSplatPrototypes[i].texture = tex;
newSplatPrototypes[i].normalMap = normal_tex;
newSplatPrototypes[i].tileSize = new Vector2(15, 15);
} else {
newSplatPrototypes[i].texture = splatPrototypes[i].texture;
newSplatPrototypes[i].normalMap = splatPrototypes[i].normalMap;
newSplatPrototypes[i].tileSize = splatPrototypes[i].tileSize;
}
}
splatPrototypes = newSplatPrototypes;
if (index + 1 > 2) {
addBlendPoints();
}
}
step 2, find the function TextureTerrain() in the same file, and add normal maps parameter to its signature:
public void TextureTerrain(float[] slopeStops, float[] heightStops, Texture2D[] textures, Texture2D[] normals) {
now find inside the function the loop that set textures (uses the function addSplatPrototype) and change to this:
int n = 0;
foreach (Texture2D tex in textures) {
addSplatPrototype(tex, normals[n], n);
n++;
}
last but not least, there's a place where the default texture is set and they use addSplatPrototype, so you need to fix it. just send null as the normal map texture:
terrain.addSplatPrototype(terrain.defaultTexture, null, nTextures);
that's it. you can now use TextureTerrain() with normal maps array and it works. As I said, its a patchy solution so if anyone got better idea I'd love to hear. :)
EDIT: I feel like I should explain why this solution is bad and add the alternative I used. its bad because it override all the splat data, including tiles, metallic, smoothness, etc. in my case, I wanted to keep those settings from the terrain instance. so eventually I removed the solution above and changed it so the function will accept null as textures list and if null will not override the existing splat prototypes. then I just define the splats via gui and create prefabs for different terrain types (forest, snow, etc..). hope it was clear enough.