Search Unity

Have Texture2Ds want alphamaps.

Discussion in 'World Building' started by sarynth, Nov 22, 2020.

  1. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    If I call `terrainData.GetAlphamapTexture()` I get a `Texture2D`. How would I then load that back into terrainData? `SetAlphamaps` requires a float[,,].
     
  2. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Ok, figured it out. I was specifically having a problem with the CTS splat maps being in a texture on the material's shader. (Or in the CTS component.) This will pull those splat maps and write them to the terrain data. Geez, took me 6 hours... :) At least it's done.

    Code (CSharp):
    1.         private void DoExport()
    2.         {
    3. #if UNITY_EDITOR
    4.             var sceneName = SceneManager.GetActiveScene().name;
    5.             var timeText = DateTime.Now.ToString("HHmmss");
    6.             var path = "Assets/Scenes/" + sceneName + "/TerrainData-" + timeText + ".asset";
    7.             Debug.Log("Saving to: " + path);
    8.  
    9.             var terrain = GetComponent<Terrain>();
    10.             var terrainData = terrain.terrainData;
    11.  
    12.             // Write the CTS splat map to the terrainData!
    13.             var splats = GenerateCtsAlphamap(terrainData);
    14.  
    15.             UnityEditor.AssetDatabase.CreateAsset(terrainData, path);
    16.  
    17.             // It is necessary to re-set and save. Unity issue?
    18.             terrainData.SetAlphamaps(0, 0, splats);
    19.             UnityEditor.AssetDatabase.SaveAssets();
    20. #endif
    21.         }
    22.  
    23.         private float[,,] GenerateCtsAlphamap(TerrainData terrainData)
    24.         {
    25.             var cts = GetComponent<CompleteTerrainShader>();
    26.             var splatList = new[] {cts.Splat1, cts.Splat2, cts.Splat3, cts.Splat4};
    27.  
    28.             // Ensure we have the correct size array.
    29.             var myMap = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight);
    30.  
    31.             // When we have a second splat. Two splats of 4 layers = 8.
    32.             // var myMap = new float[terrainData.alphamapWidth, terrainData.alphamapHeight, 8];
    33.             var layerCount = myMap.GetLength(2);
    34.  
    35.             for (var splatId = 0; splatId < 4; splatId++)
    36.             {
    37.                 var tex = splatList[splatId];
    38.                 if (tex == null) continue;
    39.  
    40.                 var colors = splatList[splatId].GetPixels();
    41.                 for (var x = 0; x < terrainData.alphamapWidth; x++)
    42.                 {
    43.                     for (var y = 0; y < terrainData.alphamapHeight; y++)
    44.                     {
    45.                         // First splat will go in slots 0, 1, 2, 3
    46.                         // Second splat will go in slots 4, 5, 6, 7
    47.                         // Texture is 513, vs alphamap is 512. This is ok, ignore the 513th element.
    48.                         // RGBA (Assume height and width are equal.)
    49.                         myMap[x, y, splatId * 4 + 0] = colors[x * splatList[splatId].width + y].r;
    50.                         if (layerCount <= splatId * 4 + 1) continue;
    51.                         myMap[x, y, splatId * 4 + 1] = colors[x * splatList[splatId].width + y].g;
    52.                         if (layerCount <= splatId * 4 + 2) continue;
    53.                         myMap[x, y, splatId * 4 + 2] = colors[x * splatList[splatId].width + y].b;
    54.                         // Sometimes there are 7 layers, so we have no where to place the 8th layer.
    55.                         if (layerCount <= splatId * 4 + 3) continue;
    56.                         myMap[x, y, splatId * 4 + 3] = colors[x * splatList[splatId].width + y].a;
    57.                     }
    58.                 }
    59.             }
    60.  
    61.             return myMap;
    62.         }
    63.  
     
    wyattt_ likes this.