Problem generating grass in terrain layers

Hi there, it’s my first topic in five years using Unity but I don’t really know how to manage this. I’ve done a compute shader supported by a c# script to generate grass in a Unity Terrain Layer. It works fine as you can see in the image, but I have a great performance issue. The valid positions of the terrain are sampled using an alpha map generated by the Unity Terrain Layer and its height map. But when I try to do this heavy operation in the cpu, a bottleneck is created for managing too much information between the cpu to gpu. I would like to implement it in the compute shader, but the something happens in the transformation and the position is not well calculated. I would appreciate any help from the people who know about compute shaders or procedural generation :slight_smile:
These are the function I use for sending de data. They already work, but I want them to be in the compute.

private void ConfigureComputeShaderWithPositions()
  {
 
      GraphicsBuffer positionsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, validPositions.Count, sizeof(float) * 3);
      positionsBuffer.SetData(validPositions);


      computeShader.SetBuffer(kernel, "_ValidPositions", positionsBuffer);
      computeShader.SetInt("_TotalPositions", validPositions.Count);
  }


  private void GeneratePositionsFromAlphaMap(TerrainData terrainData)
  {
      float[,,] alphamap = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight);
      Vector3 terrainPos = terrain.transform.position;
      Vector3 terrainSize = terrainData.size;


      int totalSamples = Mathf.CeilToInt(baseSamples * densityFactor);

      for (int i = 0; i < totalSamples; i++)
      {
        
          float x = Halton(i, 2) * terrainSize.x;
          float z = Halton(i, 3) * terrainSize.z;

     
          int alphaX = Mathf.FloorToInt((x / terrainSize.x) * terrainData.alphamapWidth);
          int alphaZ = Mathf.FloorToInt((z / terrainSize.z) * terrainData.alphamapHeight);

        
          alphaX = Mathf.Clamp(alphaX, 0, terrainData.alphamapWidth - 1);
          alphaZ = Mathf.Clamp(alphaZ, 0, terrainData.alphamapHeight - 1);

          if (alphamap[alphaZ, alphaX, terrainLayerIndex] >= grassThreshold)
          {
              Vector3 localPos = new Vector3(x, 0, z);
              Vector3 worldPos = localPos + terrainPos;
              localPos.y = terrain.SampleHeight(worldPos) - terrainPos.y;
              validPositions.Add(localPos);
          }
      }
  }