Advertisement
JontePonte

dynamic snow mesh

Jan 5th, 2025 (edited)
6
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.57 KB | None | 0 0
  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5.  
  6. public class Snow : MonoBehaviour
  7. {
  8. [Header("Appearance")]
  9. public float planeSize;
  10. public float snowHeight;
  11. public float snowSharpness;
  12.  
  13. [Header("Mesh")]
  14. public float threshold;
  15. public float errorThreshold;
  16. public int maxResolution;
  17. public int minResolution;
  18. public bool rebuild;
  19. public bool drawVertices;
  20.  
  21. [Header("")]
  22. public Transform player;
  23. public Material snowMat;
  24. public ComputeShader updateTexture;
  25. public ComputeShader buildMesh;
  26.  
  27. RenderTexture displacementMap;
  28. GameObject snowPlane;
  29. Mesh snowMesh;
  30. MeshBuilder meshBuilder;
  31.  
  32. void Start()
  33. {
  34. InitRenderTexture();
  35. InitShader();
  36. InitSnowPlane();
  37. }
  38.  
  39. void Update()
  40. {
  41. updateTexture.SetFloats("playerPos", new float[] { player.position.x, player.position.z });
  42. updateTexture.Dispatch(0, minResolution / 8, minResolution / 8, 1);
  43.  
  44. snowMat.SetTexture("_Disp", displacementMap);
  45. snowMesh = GeneratePlaneMesh2();
  46. snowPlane.GetComponent<MeshFilter>().mesh = snowMesh;
  47. snowMesh.RecalculateNormals();
  48. }
  49.  
  50. void InitShader()
  51. {
  52. updateTexture.SetFloat("maxPlayerPosX", planeSize / 2);
  53. updateTexture.SetFloat("minPlayerPosX", -(planeSize / 2));
  54. updateTexture.SetFloat("maxPlayerPosY", planeSize / 2);
  55. updateTexture.SetFloat("minPlayerPosY", -(planeSize / 2));
  56.  
  57. updateTexture.SetFloat("dstSharpness", snowSharpness);
  58. updateTexture.SetFloat("threshold", threshold);
  59.  
  60. updateTexture.SetFloat("playerRadius", player.transform.localScale.x / 2);
  61.  
  62. updateTexture.SetInt("width", minResolution);
  63. updateTexture.SetInt("height", minResolution);
  64. }
  65. void InitRenderTexture()
  66. {
  67. displacementMap = new RenderTexture(minResolution, minResolution, 24);
  68. displacementMap.enableRandomWrite = true;
  69. displacementMap.Create();
  70.  
  71. updateTexture.SetTexture(0, "Result", displacementMap);
  72. }
  73. void InitSnowPlane()
  74. {
  75. snowPlane = new GameObject("Snow Plane");
  76. snowPlane.AddComponent<MeshRenderer>().material = snowMat;
  77. snowPlane.transform.position = Vector3.up * snowHeight;
  78.  
  79. snowMesh = GeneratePlaneMesh();
  80. snowPlane.AddComponent<MeshFilter>().mesh = snowMesh;
  81.  
  82. var collider = GameObject.CreatePrimitive(PrimitiveType.Plane);
  83. collider.GetComponent<MeshRenderer>().enabled = false;
  84. collider.transform.localScale = Vector3.one * planeSize / 10;
  85. collider.transform.parent = snowPlane.transform;
  86.  
  87. snowMat.SetFloat("_DispAmount", -snowHeight);
  88. }
  89.  
  90. Mesh GeneratePlaneMesh()
  91. {
  92. if (meshBuilder == null)
  93. {
  94. meshBuilder = new MeshBuilder(planeSize, planeSize / minResolution, planeSize / maxResolution, errorThreshold);
  95. }
  96. meshBuilder.Rebuild(ToTexture2D(displacementMap));
  97.  
  98. Vector2[] uvs = new Vector2[minResolution * minResolution];
  99. for (int z = 0, i = 0; z < minResolution; z++)
  100. {
  101. for (int x = 0; x < minResolution; x++, i++)
  102. {
  103. uvs[i] = new Vector2((float)x / minResolution, (float)z / minResolution);
  104. }
  105. }
  106.  
  107. return new Mesh()
  108. {
  109. indexFormat = UnityEngine.Rendering.IndexFormat.UInt32,
  110. vertices = meshBuilder.vertices.ToArray(),
  111. triangles = meshBuilder.indices.ToArray(),
  112. uv = meshBuilder.uvs.ToArray()
  113. };
  114. }
  115.  
  116. Mesh GeneratePlaneMesh2()
  117. {
  118. Vector3[] vertices = new Vector3[minResolution * minResolution];
  119. Vector2[] uvs = new Vector2[vertices.Length];
  120. int[] indices = new int[(minResolution - 1) * (minResolution - 1) * 6];
  121.  
  122. float spacing = planeSize / minResolution;
  123.  
  124. for (int z = 0, i = 0; z < minResolution; z++)
  125. {
  126. for (int x = 0; x < minResolution; x++, i++)
  127. {
  128. vertices[i] = new Vector3(x * spacing - planeSize / 2, 0, z * spacing - planeSize / 2);
  129. uvs[i] = new Vector2((float)x / minResolution, (float)z / minResolution);
  130. }
  131. }
  132.  
  133. for (int z = 0, i = 0, j = 0; z < minResolution - 1; z++)
  134. {
  135. for (int x = 0; x < minResolution - 1; x++, i++, j += 6)
  136. {
  137. indices[j] = i;
  138. indices[j + 1] = i + (minResolution - 1) + 1;
  139. indices[j + 2] = i + 1;
  140.  
  141. indices[j + 3] = i + 1;
  142. indices[j + 4] = i + (minResolution - 1) + 1;
  143. indices[j + 5] = i + (minResolution - 1) + 2;
  144. }
  145. i++;
  146. }
  147.  
  148. return new Mesh()
  149. {
  150. indexFormat = UnityEngine.Rendering.IndexFormat.UInt32,
  151. vertices = vertices,
  152. triangles = indices,
  153. uv = uvs
  154. };
  155. }
  156.  
  157. Texture2D ToTexture2D(RenderTexture rTex)
  158. {
  159. Texture2D tex = new Texture2D(rTex.width, rTex.height);
  160. RenderTexture.active = rTex;
  161. tex.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0);
  162. tex.Apply();
  163. return tex;
  164. }
  165.  
  166. void OnDestroy()
  167. {
  168. displacementMap.Release();
  169. }
  170. }
  171.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement