Search Unity

Help Needed With Vertex Painting Unity Terrain or Retrieving Vertex Color/Position Data

Discussion in 'World Building' started by yellowskeletacc, Aug 22, 2021.

  1. yellowskeletacc

    yellowskeletacc

    Joined:
    Oct 28, 2020
    Posts:
    3
    Hello,
    I am trying to integrate unity's terrain with a custom grass renderer and the renderer needs positions in order to render the grass pieces. My best approach so far has been to export the terrain as a mesh and paint vertex colors on that separate mesh using PolyBrush and use the vertex position/color data to calculate position/density of grass. This work-around works but it would be a lot nicer if I would be able to somehow read the data from the splat maps of the terrain (because as far as I know the terrain textures are stored in the rgba channels). So if anyone knows a way to paint vertex colors on the terrain like you can do on a regular mesh using PolyBrush. Or a way to at least read the texture layer data than I would like to hear how. Or some way to convert the terrain into a unity mesh class so I can do it easier in the editor. (because I'm currently using this to export the mesh as obj and I don't really understand how it works so I kind of need a push in the right direction as to how to get the vertices)

    Thanks for any advice in advance.
     
  2. yellowskeletacc

    yellowskeletacc

    Joined:
    Oct 28, 2020
    Posts:
    3
    I managed to solve this problem so for anyone having the same problem I used this script to solve it (kind of)

    Code (CSharp):
    1. List<Vector3> GetPositions(Terrain terrain, Texture2D mask, float range, int instanceCount)
    2.     {
    3.         var positions = new List<Vector3>();
    4.  
    5.         int vertexLimit = instanceCount / mask.width * mask.height; // Grass Pos Density
    6.  
    7.         // Diagnostics and debugging
    8.         Debug.Log("Per Vertex Limit: " + vertexLimit);
    9.  
    10.         var iterations = 0;
    11.         var timer = System.Diagnostics.Stopwatch.StartNew();
    12.  
    13.         for (int x = 0; x < mask.width; x++)
    14.         {
    15.             for (int z = 0; z < mask.height; z++)
    16.             {
    17.                 for (int i = 0; i < vertexLimit * mask.GetPixel(x, z).g; i++) // Read Density
    18.                 {
    19.                     var pos = new Vector3();
    20.  
    21.                     Vector2 rndPoint = Random.insideUnitCircle * range;
    22.                     pos.x = rndPoint.x;
    23.                     pos.z = rndPoint.y;
    24.  
    25.                     pos += new Vector3((terrain.terrainData.size.x / mask.width) * x, 0, (terrain.terrainData.size.z / mask.height) * z);
    26.                     pos.y = terrain.SampleHeight(pos);
    27.  
    28.                     positions.Add(pos);
    29.                     iterations++;
    30.                 }
    31.             }
    32.         }
    33.  
    34.         // Diagnostics and debugging
    35.         timer.Stop();
    36.         Debug.Log("Total time: " + timer.ElapsedMilliseconds + "ms");
    37.  
    38.         Debug.Log("Total Iterations: " + iterations);
    39.  
    40.         return positions;
    41.     }
     
    jmarsh411 likes this.