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


		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);

I was facing the same problem and wrote a quick hack to fix it by changing toolkit code.
It’s ugly, but it works :slight_smile:

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 *= new SplatPrototype();*
  •  	if (i == index) {*

_ newSplatPrototypes*.texture = tex;_
newSplatPrototypes.normalMap = normal_tex;
_ newSplatPrototypes.tileSize = new Vector2(15, 15);
} else {
newSplatPrototypes.texture = splatPrototypes.texture;
newSplatPrototypes.normalMap = splatPrototypes.normalMap;
newSplatPrototypes.tileSize = splatPrototypes.tileSize;
splatPrototypes = newSplatPrototypes;
if (index + 1 > 2) {

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. :slight_smile:
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.