Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //MarchingCubesGPU.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class MarchingCubesGPU : MonoBehaviour
- {
- public bool smoothTerrain;
- public bool flatShaded;
- public MeshFilter meshFilter;
- public MeshCollider meshCollider;
- public float terrainSurface = 0.5f;
- public int width = 32;
- public int height = 8;
- public int depth = 31;
- float[,,] terrainMap;
- public float noiseAmp = 0.06f;
- public bool visualiseNoise = true;
- Vector3[] vertices;
- int[] triangles;
- public ComputeShader shader;
- void Start()
- {
- }
- void Update()
- {
- terrainMap = new float[width + 1, height + 1, depth + 1];
- PopulateTerrainMap();
- CreateMeshData();
- }
- public static float Noise3D(float x, float y, float z, float frequency, float amplitude, float persistence, int octave, int seed)
- {
- float noise = 0.0f;
- for (int i = 0; i < octave; ++i)
- {
- // Get all permutations of noise for each individual axis
- float noiseXY = Mathf.PerlinNoise(x * frequency + seed, y * frequency + seed) * amplitude;
- float noiseXZ = Mathf.PerlinNoise(x * frequency + seed, z * frequency + seed) * amplitude;
- float noiseYZ = Mathf.PerlinNoise(y * frequency + seed, z * frequency + seed) * amplitude;
- // Reverse of the permutations of noise for each individual axis
- float noiseYX = Mathf.PerlinNoise(y * frequency + seed, x * frequency + seed) * amplitude;
- float noiseZX = Mathf.PerlinNoise(z * frequency + seed, x * frequency + seed) * amplitude;
- float noiseZY = Mathf.PerlinNoise(z * frequency + seed, y * frequency + seed) * amplitude;
- // Use the average of the noise functions
- noise += (noiseXY + noiseXZ + noiseYZ + noiseYX + noiseZX + noiseZY) / 6.0f;
- amplitude *= persistence;
- frequency *= 2.0f;
- }
- // Use the average of all octaves
- return noise / octave;
- }
- void PopulateTerrainMap()
- {
- // The data points for terrain are stored at the corners of our "cubes", so the terrainMap needs to be 1 larger
- // than the width/height of our mesh.
- for (int x = 0; x < width + 1; x++)
- {
- for (int y = 0; y < height + 1; y++)
- {
- for (int z = 0; z < depth + 1; z++)
- {
- float thisHeight = Noise3D(x, y, z, noiseAmp, 1.0f, 0.5f, 1, 0);
- // Set the value of this point in the terrainMap.
- terrainMap[x, y, z] = thisHeight;
- }
- }
- }
- }
- void CreateMeshData()
- {
- ClearMeshData();
- shader.SetFloat("terrainSurface", terrainSurface);
- shader.SetFloats("dimensions", new float[3] { width, height, depth });
- ComputeBuffer vertexBuffer = new ComputeBuffer(vertices.Length, sizeof(float) * 3);
- vertexBuffer.SetData(vertices);
- shader.SetBuffer(0, "vertices", vertexBuffer);
- //ComputeBuffer triangleBuffer = new ComputeBuffer(triangles.Length, sizeof(int));
- //triangleBuffer.SetData(triangles);
- //shader.SetBuffer(0, "triangles", triangleBuffer);
- ComputeBuffer terrainMapBuffer = new ComputeBuffer(terrainMap.Length, sizeof(float));
- terrainMapBuffer.SetData(terrainMap);
- shader.SetBuffer(0, "terrainMap", terrainMapBuffer);
- shader.Dispatch(0, width / 1, height / 1, depth / 1);
- vertexBuffer.GetData(vertices);
- //triangleBuffer.GetData(triangles);
- terrainMapBuffer.GetData(terrainMap);
- vertexBuffer.Release();
- //triangleBuffer.Release();
- terrainMapBuffer.Release();
- MakeTriangles();
- BuildMesh();
- }
- void MakeTriangles()
- {
- List<int> tempTrianges = new List<int>();
- for (int i = 0; i < vertices.Length; i++)
- {
- if (vertices[i] != Vector3.zero)
- {
- tempTrianges.Add(i);
- }
- }
- triangles = tempTrianges.ToArray();
- }
- void ClearMeshData()
- {
- vertices = new Vector3[width * height * depth * 15];
- //triangles = new int[width * height * depth * 15];
- }
- void BuildMesh()
- {
- Mesh mesh = new Mesh();
- mesh.vertices = vertices;
- mesh.triangles = triangles;
- mesh.RecalculateNormals();
- meshFilter.mesh = mesh;
- meshCollider.sharedMesh = mesh;
- }
- void OnDrawGizmosSelected()
- {
- if (!visualiseNoise || !Application.isPlaying)
- {
- return;
- }
- for (int x = 0; x < width + 1; x++)
- {
- for (int y = 0; y < height + 1; y++)
- {
- for (int z = 0; z < depth + 1; z++)
- {
- if (terrainMap[x, y, z] > terrainSurface)
- {
- Gizmos.color = new Color(terrainMap[x, y, z], terrainMap[x, y, z], terrainMap[x, y, z], 1.0f);
- Gizmos.DrawSphere(new Vector3(x, y, z), 0.2f);
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement