123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- namespace AmazingAssets.TerrainToMesh.Example
- {
- [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
- public class ExportGrass : MonoBehaviour
- {
- public TerrainData terrainData;
- public int vertexCountHorizontal = 100;
- public int vertexCountVertical = 100;
- void Start()
- {
- if (terrainData == null)
- return;
- //1. Export mesh from terrain////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- Mesh terrainMesh = terrainData.TerrainToMesh().ExportMesh(vertexCountHorizontal, vertexCountVertical, TerrainToMesh.Normal.CalculateFromMesh);
- GetComponent<MeshFilter>().sharedMesh = terrainMesh;
-
- //2. Create material////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- string shaderName = Utilities.GetUnityDefaultShader(); //Default shader based on used render pipeline
- Material material = new Material(Shader.Find(shaderName));
- GetComponent<Renderer>().sharedMaterial = material;
- //3. Export grass//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- DetailPrototypesData[] detailPrototypesData = terrainData.TerrainToMesh().ExportGrassData(vertexCountHorizontal, vertexCountVertical, 1, 1, 8, 1);
-
- Mesh grassMesh = Utilities.CreateGrassMesh(1); //Create grass quad mesh
- Shader grassShader = Shader.Find(Constants.shaderGrass); //Simple Mobile/Diffuse shader with Alpha cutout
- string mainTexturePropName = Utilities.GetMaterailPropMainTex(); //_MainTex property name inside shader.
- //Instantiate grass objects
- for (int t = 0; t < detailPrototypesData.Length; t++)
- {
-
- GameObject grassParent = new GameObject("Grass"); //Used as parent for all current type of grass objects
- grassParent.transform.SetParent(this.gameObject.transform, false);
- //Each type of grass needs its own material with texture from prototype
- Material grassMaterial = new Material(grassShader);
- grassMaterial.SetTexture(mainTexturePropName, detailPrototypesData[t].detailPrototype.prototypeTexture);
-
-
- for (int p = 0; p < detailPrototypesData[t].position.Count; p++)
- {
- GameObject grass = new GameObject("Grass");
- //Use quad mesh for grass
- grass.AddComponent<MeshFilter>().sharedMesh = grassMesh;
- //Assign material
- grass.AddComponent<MeshRenderer>().sharedMaterial = grassMaterial;
- //Assign parent
- grass.transform.SetParent(grassParent.transform, true);
- //Position
- grass.transform.localPosition = detailPrototypesData[t].position[p];
- //Add random rotation
- grass.transform.localRotation = Quaternion.Euler(0, Random.value * 360, 0);
- //Scale
- grass.transform.localScale = detailPrototypesData[t].scale[p];
- }
- //After all grass objects of the current type are created, it is better to combine them into one mesh
- List<Mesh> combinedMeshes = Utilities.CombineGameObjects(grassParent, grassMaterial, "Grass", detailPrototypesData[t].detailPrototype.prototypeTexture.name, UnityEngine.Rendering.IndexFormat.UInt16);
- //Bake grass Healthy and Dry color inside vertex color
- foreach (var mesh in combinedMeshes)
- {
- BakeHealthyAndDryColorsInsideVertexColor(mesh, detailPrototypesData[t].detailPrototype);
- }
- }
- }
- void BakeHealthyAndDryColorsInsideVertexColor(Mesh mesh, DetailPrototype detailPrototype)
- {
- Vector3[] vertexPosition = mesh.vertices;
- Color[] colors = mesh.colors; //Mesh already contains 'Alpha' value for Top and Bottom position
- Color healthyColor = detailPrototype.healthyColor;
- healthyColor.a = 1;
- Color dryColor = detailPrototype.dryColor;
- dryColor.a = 1;
- for (int i = 0; i < vertexPosition.Length; i++)
- {
- float pNoise = Mathf.PerlinNoise(vertexPosition[i].x * detailPrototype.noiseSpread, vertexPosition[i].z * detailPrototype.noiseSpread);
- //Multiply with existing color
- colors[i] *= Color.Lerp(dryColor, healthyColor, pNoise);
- }
- mesh.colors = colors;
- }
- }
- }
|