RunTime_Terrain_Convertion.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using UnityEngine;
  2. using System.Collections;
  3. using VacuumShaders.TerrainToMesh;
  4. [AddComponentMenu("VacuumShaders/Terrain To Mesh/Example/Runtime Converter")]
  5. public class RunTime_Terrain_Convertion : MonoBehaviour
  6. {
  7. //////////////////////////////////////////////////////////////////////////////
  8. // //
  9. //Variables //
  10. // //
  11. //////////////////////////////////////////////////////////////////////////////
  12. public Terrain sourceTerrain;
  13. public TerrainConvertInfo convertInfo;
  14. public bool generateBasemap;
  15. public bool attachMeshCollider;
  16. //////////////////////////////////////////////////////////////////////////////
  17. // //
  18. //Functions //
  19. // //
  20. //////////////////////////////////////////////////////////////////////////////
  21. void Start ()
  22. {
  23. if (sourceTerrain != null)
  24. {
  25. //Convert Terrain
  26. Mesh[] generatedMeshes = TerrainToMeshConverter.Convert(sourceTerrain, convertInfo, false);
  27. //Setup game object
  28. if (generatedMeshes != null)
  29. {
  30. //Create shared material
  31. Material sharedMat = null;
  32. if (generateBasemap)
  33. sharedMat = GenerateMaterial_Basemap();
  34. else
  35. sharedMat = GenerateMaterial_Splatmap();
  36. if (generatedMeshes.Length == 1)
  37. {
  38. //Setup MeshFilter
  39. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  40. if (mf == null)
  41. mf = gameObject.AddComponent<MeshFilter>();
  42. mf.sharedMesh = generatedMeshes[0];
  43. //Setup MeshRenderer
  44. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  45. if (mr == null)
  46. mr = gameObject.AddComponent<MeshRenderer>();
  47. mr.sharedMaterial = sharedMat;
  48. //Add MeshCollider and setup collider mesh
  49. if(attachMeshCollider)
  50. {
  51. gameObject.AddComponent<MeshCollider>().sharedMesh = mf.sharedMesh;
  52. }
  53. }
  54. else
  55. {
  56. //Create full hierarchy
  57. for (int i = 0; i < generatedMeshes.Length; i++)
  58. {
  59. //Create child object
  60. GameObject terraMeshObj = new GameObject(generatedMeshes[i].name);
  61. terraMeshObj.transform.parent = gameObject.transform;
  62. terraMeshObj.transform.localPosition = Vector3.zero;
  63. //Add mesh filter
  64. MeshFilter mf = terraMeshObj.AddComponent<MeshFilter>();
  65. mf.sharedMesh = generatedMeshes[i];
  66. //Add mesh renderer
  67. MeshRenderer mr = terraMeshObj.AddComponent<MeshRenderer>();
  68. mr.sharedMaterial = sharedMat;
  69. //Add MeshCollider and setup collider mesh
  70. if(attachMeshCollider)
  71. {
  72. terraMeshObj.AddComponent<MeshCollider>().sharedMesh = mf.sharedMesh;
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. Material GenerateMaterial_Basemap()
  80. {
  81. //Export basemaps (diffuse and normal)
  82. Texture2D basemapDiffuse = null;
  83. Texture2D basemapNormal = null;
  84. bool sRGB = QualitySettings.activeColorSpace == ColorSpace.Linear;
  85. TerrainToMeshConverter.ExtractBasemap(sourceTerrain, out basemapDiffuse, out basemapNormal, 1024, 1024, sRGB);
  86. Material newMaterial = new Material(Shader.Find(basemapNormal != null ? "Legacy Shaders/Bumped Diffuse" : "Legacy Shaders/Diffuse"));
  87. newMaterial.mainTexture = basemapDiffuse;
  88. if (basemapNormal != null)
  89. newMaterial.SetTexture("_BumpMap", basemapNormal);
  90. return newMaterial;
  91. }
  92. Material GenerateMaterial_Splatmap()
  93. {
  94. Material newMaterial = null;
  95. //Export terrain splatmaps
  96. Texture2D[] splatMap = TerrainToMeshConverter.ExtractSplatmaps(sourceTerrain);
  97. if (splatMap == null || splatMap.Length == 0)
  98. return newMaterial;
  99. //Export diffuse/normal textures
  100. Texture2D[] diffuseTextures;
  101. Texture2D[] normalTextures;
  102. Vector2[] uvScale;
  103. Vector2[] uvOffset;
  104. float[] metalic;
  105. float[] smoothness;
  106. int usedTexturesCount = TerrainToMeshConverter.ExtractTexturesInfo(sourceTerrain, out diffuseTextures, out normalTextures, out uvScale, out uvOffset, out metalic, out smoothness);
  107. if (usedTexturesCount == 0 || diffuseTextures == null)
  108. {
  109. //Problems with terrain
  110. Debug.LogWarning("usedTexturesCount == 0");
  111. return newMaterial;
  112. }
  113. else if (usedTexturesCount == 1)
  114. {
  115. //There is no need to use TerrainToMesh shaders with one texture
  116. Shader shader = Shader.Find("Legacy Shaders/Diffuse");
  117. if (shader != null)
  118. {
  119. newMaterial = new Material(shader);
  120. //Texture
  121. newMaterial.mainTexture = diffuseTextures[0];
  122. //Scale & Offset
  123. newMaterial.mainTextureScale = uvScale[0];
  124. newMaterial.mainTextureOffset = uvOffset[0];
  125. }
  126. return newMaterial;
  127. }
  128. //Terrain To Mesh shaders support max 8 textures blend
  129. usedTexturesCount = Mathf.Clamp(usedTexturesCount, 2, 8);
  130. //T2M shaders support only 4 bump maps.
  131. bool canBeUsedBump = false;
  132. if(normalTextures != null && usedTexturesCount < 5)
  133. canBeUsedBump = true;
  134. //Select proper shader
  135. Shader ttmShader = Shader.Find(string.Format("VacuumShaders/Terrain To Mesh/Standard/" + (canBeUsedBump ? "Bumped" : "Diffuse") + "/{0} Textures", usedTexturesCount));
  136. if (ttmShader == null)
  137. {
  138. Debug.LogWarning("Shader not found: " + string.Format("VacuumShaders/Terrain To Mesh/Standard/" + (canBeUsedBump ? "Bumped" : "Diffuse") + "/{0} Textures", usedTexturesCount));
  139. return newMaterial;
  140. }
  141. //Select shader
  142. newMaterial = new Material(ttmShader);
  143. //Set up controll textures
  144. if (splatMap.Length == 1)
  145. {
  146. newMaterial.SetTexture("_V_T2M_Control", splatMap[0]);
  147. }
  148. else
  149. {
  150. if (splatMap.Length > 2)
  151. Debug.Log("TerrainToMesh shaders support max 2 control textures. Current terrain uses " + splatMap.Length);
  152. newMaterial.SetTexture("_V_T2M_Control", splatMap[0]);
  153. newMaterial.SetTexture("_V_T2M_Control2", splatMap[1]);
  154. }
  155. //Assign textures
  156. for (int i = 0; i < usedTexturesCount; i++)
  157. {
  158. //Texture
  159. newMaterial.SetTexture(string.Format("_V_T2M_Splat{0}", i + 1), diffuseTextures[i]);
  160. //Scale
  161. newMaterial.SetFloat(string.Format("_V_T2M_Splat{0}_uvScale", i + 1), uvScale[i].x);
  162. //Metalic & Gloss
  163. newMaterial.SetFloat(string.Format("_V_T2M_Splat{0}_Metallic", i + 1), metalic[i]);
  164. newMaterial.SetFloat(string.Format("_V_T2M_Splat{0}_Glossiness", i + 1), smoothness[i]);
  165. //Bumpmap
  166. if(canBeUsedBump)
  167. newMaterial.SetTexture(string.Format("_V_T2M_Splat{0}_bumpMap", i + 1), normalTextures[i]);
  168. }
  169. return newMaterial;
  170. }
  171. }