protected override bool CalculateVoxel(Voxel voxel, int x, int y, int z) { float noiseValue = fractalNoise.Sample3D(offset.x + x / (float)width, y / (float)height, offset.y + z / (float)length); voxel.Data = noiseValue; return(true); }
/*public override void NodeGUI () * { * GUILayout.BeginHorizontal(); * GUILayout.BeginVertical(); * xConnection.DisplayLayout (); * yConnection.DisplayLayout (); * zConnection.DisplayLayout (); * GUILayout.EndVertical(); * outputConnection.DisplayLayout(); * GUILayout.EndHorizontal (); * }*/ public override bool Calculate() { float x = xConnection.GetValue <float>(); float y = yConnection.GetValue <float>(); float z = zConnection.GetValue <float>(); float noiseValue = fractal.Sample3D(x, y, z); outputConnection.SetValue <float>(noiseValue); return(true); }
private float[] GenerateFractalVoxels(int width, int height, int length) { INoise perlin = new PerlinNoise(seed, 2.0f); FractalNoise fractal = new FractalNoise(perlin, 3, .5f); float[] voxels = new float[width * height * length]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { float fx = x / (width - 1f); float fy = y / (height - 1f); float fz = z / (length - 1f); int idx = x + y * width + z * width * height; voxels[idx] = fractal.Sample3D(fx, fy, fz); } } } return(voxels); }
void Start() { INoise perlin = new PerlinNoise(seed, 2.0f); FractalNoise fractal = new FractalNoise(perlin, 3, 1.0f); //Set the mode used to create the mesh. //Cubes is faster and creates less verts, tetrahedrons is slower and creates more verts but better represents the mesh surface. Marching marching = null; if (mode == MARCHING_MODE.TETRAHEDRON) { marching = new MarchingTertrahedron(); } else { marching = new MarchingCubes(); } //Surface is the value that represents the surface of mesh //For example the perlin noise has a range of -1 to 1 so the mid point is where we want the surface to cut through. //The target value does not have to be the mid point it can be any value with in the range. marching.Surface = 0.0f; //The size of voxel array. int width = 32; int height = 32; int length = 10; float[] voxels = new float[width * height * length]; //Fill voxels with values. Im using perlin noise but any method to create voxels will work. for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { float fx = x / (width - 1.0f); float fy = y / (height - 1.0f); float fz = z / (length - 1.0f); int idx = x + y * width + z * width * height; voxels[idx] = fractal.Sample3D(fx, fy, fz); } } } List <Vector3> verts = new List <Vector3>(); List <int> indices = new List <int>(); //The mesh produced is not optimal. There is one vert for each index. //Would need to weld vertices for better quality mesh. marching.Generate(voxels, width, height, length, verts, indices); //A mesh in unity can only be made up of 65000 verts. //Need to split the verts between multiple meshes. int maxVertsPerMesh = 30000; //must be divisible by 3, ie 3 verts == 1 triangle int numMeshes = verts.Count / maxVertsPerMesh + 1; for (int i = 0; i < numMeshes; i++) { List <Vector3> splitVerts = new List <Vector3>(); List <int> splitIndices = new List <int>(); for (int j = 0; j < maxVertsPerMesh; j++) { int idx = i * maxVertsPerMesh + j; if (idx < verts.Count) { splitVerts.Add(verts[idx]); splitIndices.Add(j); } } if (splitVerts.Count == 0) { continue; } Mesh mesh = new Mesh(); mesh.SetVertices(splitVerts); mesh.SetTriangles(splitIndices, 0); mesh.RecalculateBounds(); mesh.RecalculateNormals(); GameObject go = new GameObject("Mesh"); go.transform.parent = transform; go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = m_material; go.GetComponent <MeshFilter>().mesh = mesh; go.transform.localPosition = new Vector3(-width / 2, -height / 2, -length / 2); meshes.Add(go); } }
public void InitialiseVoxels() { if (RockNoiseLayer) { RockNoiseLayer.Initialise(); } if (DirtNoiseLayer) { DirtNoiseLayer.Initialise(); } INoise noise = GetNoise(m_noiseType, 0, m_frequency, m_amplitude); FractalNoise fractalNoise = new FractalNoise(noise, m_octaves, m_frequency, m_amplitude); for (int x = 0; x < chunkSizeXZ; x++) { for (int z = 0; z < chunkSizeXZ; z++) { float bedrockHeight = 2; float rockHeight = 0; float dirtHeight = 0; //float sandHeight = 12; if (RockNoiseLayer) { rockHeight += RockNoiseLayer.SampleValue( x / (float)(m_worldResolution - 1), z / (float)(m_worldResolution - 1) ); } if (DirtNoiseLayer) { dirtHeight += DirtNoiseLayer.SampleValue( x / (float)(m_worldResolution - 1), z / (float)(m_worldResolution - 1) ); } for (int y = 0; y < chunkHeight; y++) { Voxel v = voxelGrid[x, y, z]; if (x == 0 || x == chunkSizeXZ - 1 || y == 0 || y == chunkHeight - 1 || z == 0 || z == chunkSizeXZ - 1) { v.VoxelType = 0; v.Value = 0; } else { if (y <= bedrockHeight) { v.VoxelType = 1; } else if (y <= rockHeight) { v.VoxelType = 2; } else if (y <= dirtHeight) { v.VoxelType = 3; } //else if (y <= sandHeight) //{ // v.VoxelType = 4; //} else { v.VoxelType = 0; } float pointValue = fractalNoise.Sample3D( x / (float)(m_worldResolution - 1), y / (float)(m_worldResolution - 1), z / (float)(m_worldResolution - 1) ); v.Value = pointValue; } } } } }
void Generate() { DateTime startTime = System.DateTime.Now; INoise perlin = new PerlinNoise(seed, 2f); FractalNoise fractal = new FractalNoise(perlin, 3, 1f); MarchingCube marching = new MarchingCube(); Marching.Surface = 0f; width = sizeScale; height = sizeScale; length = sizeScale; float[] voxels = new float[width * height * length]; //Fill voxels with values. Im using perlin noise but any method to create voxels will work. for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { float fx = x / (width - 1.0f); float fy = y / (height - 1.0f); float fz = z / (length - 1.0f); int idx = x + y * width + z * width * height; voxels[idx] = fractal.Sample3D(fx, fy, fz); } } } verts = new List <Vector3>(); indices = new List <int>(); if (useJobSystem) { MarchingCubeParallel marching_p = new MarchingCubeParallel(0); MarchingCubeParallel.MarchJob job; JobHandle handle = marching_p.Generate(new List <float>(voxels), width, height, length, out job); StartCoroutine(Wait4Complete(handle, job)); } else { marching.Generate(voxels, width, height, length, verts, indices); int maxVertsPerMesh = 30000; //must be divisible by 3, ie 3 verts == 1 triangle int numMeshes = verts.Count / maxVertsPerMesh + 1; for (int i = 0; i < numMeshes; i++) { List <Vector3> splitVerts = new List <Vector3>(); List <int> splitIndices = new List <int>(); for (int j = 0; j < maxVertsPerMesh; j++) { int idx = i * maxVertsPerMesh + j; if (idx < verts.Count) { splitVerts.Add(verts[idx]); splitIndices.Add(j); } } if (splitVerts.Count == 0) { continue; } Mesh mesh = new Mesh(); mesh.SetVertices(splitVerts); mesh.SetTriangles(splitIndices, 0); mesh.RecalculateBounds(); mesh.RecalculateNormals(); GameObject go = new GameObject("Mesh"); go.transform.parent = transform; go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = m_material; go.GetComponent <MeshFilter>().mesh = mesh; go.transform.localPosition = new Vector3(-width / 2, -height / 2, -length / 2); meshes.Add(go); } } double timeCost = System.DateTime.Now.Subtract(startTime).TotalMilliseconds; print("Time Cost : " + timeCost + " at size " + (8 * sizeScale)); }
void Start() { INoise perlin = new PerlinNoise(seed, 2.0f); FractalNoise fractal = new FractalNoise(perlin, 3, 1.0f); //Set the mode used to create the mesh. //Cubes is faster and creates less verts, tetrahedrons is slower and creates more verts but better represents the mesh surface. Marching marching = null; if (mode == MARCHING_MODE.TETRAHEDRON) { marching = new MarchingTertrahedron(); } else { marching = new MarchingCubes(); } //Surface is the value that represents the surface of mesh //For example the perlin noise has a range of -1 to 1 so the mid point is where we want the surface to cut through. //The target value does not have to be the mid point it can be any value with in the range. marching.Surface = 0.0f; //The size of voxel array. int width = 32; int height = 32; int length = 32; float[] voxels = new float[width * height * length]; //Fill voxels with values. Im using perlin noise but any method to create voxels will work. for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { float fx = x / (width - 1.0f); float fy = y / (height - 1.0f); float fz = z / (length - 1.0f); int idx = x + y * width + z * width * height; voxels[idx] = fractal.Sample3D(fx, fy, fz); } } } List <Vector3> verts = new List <Vector3>(); List <int> indices = new List <int>(); System.Diagnostics.Stopwatch measure = new System.Diagnostics.Stopwatch(); measure.Start(); marching.Generate(voxels, width, height, length, verts, indices); verts = MeshUtils.WeldVertices(verts, indices); measure.Stop(); Debug.Log(string.Format("Time elapsed: {0}", measure.Elapsed)); Mesh mesh = new Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; mesh.SetVertices(verts); mesh.SetTriangles(indices, 0); mesh.RecalculateBounds(); mesh.RecalculateNormals(); GameObject go = new GameObject("Mesh"); go.transform.parent = transform; go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = m_material; go.GetComponent <MeshFilter>().mesh = mesh; go.transform.localPosition = new Vector3(-width / 2, -height / 2, -length / 2); }