Terrain To Mesh
  • Terrain To Mesh
  • Quick Start
  • Editor Window Settings
    • Mesh
    • Material
    • Objects
    • Save
  • Update Splatmap Shader
  • Run-time API
    • TerrainToMesh
      • ExportMesh
      • ExportTerrainLayers
      • ExportSplatmapMaterial
      • ExportSplatmapTextures
      • HasHoles
      • ExportHolesmapTexture
      • ExportBasemapDiffuseTexture
      • ExportBasemapNormalTexture
      • ExportBasemapMaskTexture
      • ExportBasemapOcclusionTexture
      • ExportGrassTextures
      • ExportGrassAtlasTexture
      • HasPrototypes
      • CountPrototypes
      • ExportPrototypes
    • TerrainToMeshUtilities
      • GenerateGrassMesh
      • GenerateEdgeFallTexture
      • ConvertMeshToOBJ
      • ConvertMeshToOBJAndSaveToFile
      • ConvertMeshToOBJAndAppendToFile
      • GetDefaultMaterial
      • GetDefaultShader
      • GetDefaultShaderProperty
      • SetupDefaultMaterial
      • SetupAlphaCutoutForDefaultMaterial
      • ConvertPrototypesToTreeGameObjects
      • ConvertPrototypesToGrassGameObjects
      • ConvertPrototypesToGrassMeshes
      • ConvertPrototypesToDetailMeshGameObjects
      • ConvertPrototypesToDetailMeshes
      • CalculateExportedMeshVertexCount
      • SetMeshPivotPoint
    • TerrainToMeshEdgeFall
    • TerrainToMeshPrototype
    • TerrainToMeshConversionDetails
  • Help & Contact
Powered by GitBook
On this page
PreviousConvertPrototypesToGrassGameObjectsNextConvertPrototypesToDetailMeshGameObjects

Last updated 1 month ago

Convert Prototypes To Grass Meshes

Dictionary<int, Mesh[]> ConvertPrototypesToGrassMeshes(TerrainToMeshPrototype[] data, TerrainToMeshEnum.GrassCombineType grassCombineType, TerrainToMeshEnum.GrassMeshTexcoord2 grassMeshTexcoord2, bool calculateHealthAndDryColor, Dictionary<Texture2D, Rect> atlasRect, float exportPercentage, int maxVertexCountPerCombinedMesh, int grassMeshSidesCount = 1, float grassMeshDistortion = 0, float yRotation = 360, float yRotationRandomize = 360, float followTerrainSurface = 0, bool followTerrainSurfaceRandomize = false)

Combines grass objects into one or several meshes.

Returned dictionary key is the grass index inside array and value holds the combined meshes associated to that index.

grassCombineType - Grass meshes combine type:

  • GrassCombineType.ByTexture - Grass meshes are combined based on the used grass texture.

  • GrassCombineType.ByTextureWithAtlas - Grass meshes are combined based on the used grass texture and mesh UV is generated based on the provided GrassAtlasTexture.

  • GrassCombineType.Everything - Combines all grass meshes into one file and for each mesh UV is generated based on the provided GrassAtlasTexture.

grassMeshTexcoord2 - Allows baking additional data inside combed meshes UV channel #2:

  • GrassMeshTexcoord2.None - Nothing is baked.

  • GrassMeshTexcoord2.PivotPoint - Bakes current grass quad mesh's pivot point's local position.

  • GrassMeshTexcoord2.BaseUV - Bakes current grass quad mesh's initial UV coordinates that will be overwritten in the case of using GrassAtlasTexture.

Dictionary<Texture2D, Rect> atlasRect - In the case of using GrassAtlasTexture, this property should provide collection of GrassTextures and UV coordinates associated with this texture inside GrassAtlasTexture.

exportPercentage - Percentage of the combined grass objects in the range of [0.01, 100]

maxVertexCountPerCombinedMesh - Defines how much vertices combined mesh(es) will contain.

int grassMeshSidesCount, float grassMeshDistortion - Specifies how much sides each grass quad mesh will contain and how much offset distortion they will have.

//Example of exporting grass from TerrainData 
//and generating combined meshes by used texture

//Exporting terrain mesh
Mesh terrainMesh = terrainData.TerrainToMesh().ExportMesh(100, 100);

//Creaing GameObject using terrain mesh
GameObject terrainGO = new GameObject("Terrain");
terrainGO.AddComponent<MeshFilter>().sharedMesh = terrainMesh;
terrainGO.AddComponent<MeshRenderer>().sharedMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());


//Exporting grass from TerrainData
TerrainToMeshPrototype[] grassPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.Grass);

//Combining 100% of grassPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> grassMeshes = TerrainToMeshUtilities.ConvertPrototypesToGrassMeshes(grassPrototypes,
                                                                                            TerrainToMeshEnum.GrassCombineType.ByTexture,
                                                                                            TerrainToMeshEnum.GrassMeshTexcoord2.None,
                                                                                            true,
                                                                                            null,
                                                                                            100,
                                                                                            65000);


//Creating materials for each layer
Dictionary<int, Material> grassMaterials = new Dictionary<int, Material>();
foreach (var item in grassMeshes)
{
    Texture2D grassTexture = terrainData.detailPrototypes[item.Key].prototypeTexture;

    Material material = new Material(TerrainToMeshUtilities.GetDefaultShader());
    
    //Setting up material to use grass texture for '_MainTex' and enabling Alpha Cutout
    TerrainToMeshUtilities.SetupDefaultMaterial(material, grassTexture, true, null, null, null);

    material.name = grassTexture.name;


    grassMaterials.Add(item.Key, material);
}

//Instantiating gameObject with grass meshes
foreach (var item in grassMeshes)
{
    Mesh[] meshes = item.Value;
    for (int i = 0; i < meshes.Length; i++)
    {
        GameObject grassGO = new GameObject($"Grass (Layer : {item.Key}) {grassMaterials[item.Key].name}");

        grassGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
        grassGO.AddComponent<MeshRenderer>().sharedMaterial = grassMaterials[item.Key];

        grassGO.transform.SetParent(terrainGO.transform);
    }
}
//Example of exporting grass from TerrainData, 
//and generating combined meshes by used texture

//Exporting terrain mesh
Mesh terrainMesh = terrainData.TerrainToMesh().ExportMesh(100, 100);

//Creaing GameObject using terrain mesh
GameObject terrainGO = new GameObject("Terrain");
terrainGO.AddComponent<MeshFilter>().sharedMesh = terrainMesh;
terrainGO.AddComponent<MeshRenderer>().sharedMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());


//Exporting grass from TerrainData
TerrainToMeshPrototype[] grassPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.Grass);

//Exporting grass atlas texture from TerrainData
Dictionary<Texture2D, Rect> atlasUVRect;
Texture2D grassAtlasTexture = terrainData.TerrainToMesh().ExportGrassAtlasTexture(1024, out atlasUVRect);

//Combining 100% of grassPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> grassMeshes = TerrainToMeshUtilities.ConvertPrototypesToGrassMeshes(grassPrototypes,
                                                                                            TerrainToMeshEnum.GrassCombineType.ByTextureWithAtlas,
                                                                                            TerrainToMeshEnum.GrassMeshTexcoord2.None,
                                                                                            true,
                                                                                            atlasUVRect,
                                                                                            100,
                                                                                            65000);
                                                                                                    
//Creating material using GrassAtlasTexture
Material grassAtlasMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());
grassAtlasMaterial.name = terrainData.name + " Grass Atlas";

//Setting up material to use GrassAtlasTexture for '_MainTex' and enabling Alpha Cutout
TerrainToMeshUtilities.SetupDefaultMaterial(grassAtlasMaterial, grassAtlasTexture, true, null, null, null);


//Instantiating gameObject with grass meshes
foreach (var item in grassMeshes)
{
    Mesh[] meshes = item.Value;
    for (int i = 0; i < meshes.Length; i++)
    {
        GameObject grassGO = new GameObject($"Grass (Layer: {item.Key})");

        grassGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
        grassGO.AddComponent<MeshRenderer>().sharedMaterial = grassAtlasMaterial;

        grassGO.transform.SetParent(terrainGO.transform);
    }
}
//Example of exporting grass from TerrainData 
//and combining them all into one mesh

//Exporting terrain mesh
Mesh terrainMesh = terrainData.TerrainToMesh().ExportMesh(100, 100);

//Creaing GameObject using terrain mesh
GameObject terrainGO = new GameObject("Terrain");
terrainGO.AddComponent<MeshFilter>().sharedMesh = terrainMesh;
terrainGO.AddComponent<MeshRenderer>().sharedMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());


//Exporting grass from TerrainData
TerrainToMeshPrototype[] grassPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.Grass);


//Exporting grass atlas texture from TerrainData
Dictionary<Texture2D, Rect> atlasUVRect;
Texture2D grassAtlasTexture = terrainData.TerrainToMesh().ExportGrassAtlasTexture(1024, out atlasUVRect);

//Combining 100% of grassPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> grassMeshes = TerrainToMeshUtilities.ConvertPrototypesToGrassMeshes(grassPrototypes,
                                                                                            TerrainToMeshEnum.GrassCombineType.Everything,
                                                                                            TerrainToMeshEnum.GrassMeshTexcoord2.None,
                                                                                            true,
                                                                                            atlasUVRect,
                                                                                            100,
                                                                                            65000);
                                                                                                   
//Creating material using GrassAtlasTexture
Material grassAtlasMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());
grassAtlasMaterial.name = terrainData.name + " Grass Atlas";

//Setting up material to use GrassAtlasTexture for '_MainTex' and enabling Alpha Cutout
TerrainToMeshUtilities.SetupDefaultMaterial(grassAtlasMaterial, grassAtlasTexture, true, null, null, null);
                   

//Instantiating gameObject with grass meshes
foreach (var item in grassMeshes)
{
    Mesh[] meshes = item.Value;
    for (int i = 0; i < meshes.Length; i++)
    {
        GameObject grassGO = new GameObject("Grass");

        grassGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
        grassGO.AddComponent<MeshRenderer>().sharedMaterial = grassAtlasMaterial;

        grassGO.transform.SetParent(terrainGO.transform);
    }
}

calculateHealthAndDryColor - Bakes prototype's and colors.

Theoretically Unity can create mesh with 4 billion vertices, but for run-time use it is better to use more logical values. Based on the used vertex count, generated meshes will be in 16 or 32 bits .

health
dry
index format
TerrainToMeshPrototypes
TerrainData.detailPrototypes