- Home /
Cube World Terrain generation
ive have been working on a voxel game, and have decided to tackle word generation using perlin noise, i managed to create simple terrain easily
but i wanted to create more interesting cube world sytled terrain
ive been trying for 2 hours and have made no progress (and yes i have seen all the other posts) so i decided to ask the internet
Heres the code i used to create the simple terrain
void Start () {
float posX = transform.position.x;
float posZ = transform.position.z;
for (int y = 0; y < chunkY; y++) {
for (int z = 0; z < chunkZ; z++) {
for (int x = 0; x < chunkX; x++) {
//Terrain algorithm
float flatNoise = Mathf.Round (Mathf.PerlinNoise ((transform.position.x + x) * Flatscale, (transform.position.z + z) * Flatscale ) * 10);
float height = flatNoise;
Vector3 pos = new Vector3 (posX, height, posZ);
GameObject newBlock = Instantiate (block, pos, Quaternion.identity) as GameObject;
newBlock.transform.parent = this.transform;
posX += 1;
}
posX = transform.position.x;
posZ += 1;
}
posX = transform.position.x;
posZ = transform.position.z;
}
}
Note: chunk x, y and z are just sizes
Answer by Remy_Unity · Dec 08, 2017 at 11:56 AM
The issue is that your code is only using the 2D noise to generate height data. To have more complex terrain like one you give as exemple, you will need to use 3D noise generation to create "density" data.
And with this you should then be able to generate the cubes.
To simplify the idea : instead of cube.pos.y = noise(x, z) do : if (noise(x,y,z) > 0.5) placeCube .
There is no 3D perlin in Unity, but you can hack it with Mathf.PerlinNoise(x, Mathf.PerlinNoise(y, z))
Answer by Dray · Dec 08, 2017 at 12:08 PM
The main issue here is that you are using a 2D Noise function to generate 3D data, which causes all your blocks with the same x/z coordinate to spawn at the same y position. But let me complement this;
First off, you really got to understand how voxel data is managed. You could easily describe a voxel as the three dimensional pendant to a pixel.
When working with heightmaps (=pixel data), your height is stored in a two dimensional surface, (most likely a heightmap texture) where you can recieve an Y value for each two dimensional X/Z coordinate on your map.
Voxels though are stored in a three dimensional grid, or a so called volume, where each X/Y/Z index has his own value. For simplicity let's say this could be a boolean, so your volume data would be something like:
bool[,,] volume = new bool[chunkX, chunkY, chunkZ];
You can fill that data using a 3D Noise function. I found this implementation of simplex noise earlier, maybe it can help you.
Then the next step would be to iterate over the volumes x,y,z indices, as you are actually doing allready. Recieve the data of the current block by simply reading the value from your volume and then spawn a block if the value is 'true':
bool spawnBlock = volume[x, y, z];
if (spawnBlock) {
Vector3 pos = new Vector3 (x, y, z) * blockScale;
// spawn code here ...
}
EDIT: Allright @Remy_Unity was quicker :D I suggest you to look at both answers since his shows you how to map a heightmap onto a voxel grid correctly and mine shows you how to generate the 3d noise shapes that produce caves and overhangs. If you combine both, you'll get a good looking basic voxel terrain :)
Looking at @Dray message, I realize I'm really bad at formatting here ...
Also note that using any of the higher methods will make you generate cubes everywhere your volume function returns true. Doing this is highly non-optimal, as most of those cubes will not be visible because they will be surrounded by others.
In games like $$anonymous$$ecraft and cubework, the generated terrain is not composed of cubes spawn everywhere but of quad faces that only represent the surface of the volume.
It's maybe a little soon to talk about this optimisation, but keep it in $$anonymous$$d.
I totally agree Remy ;) There are big performance issues in this solution but I think for $$anonymous$$lasmic it's to early to start building his own polygonization algorythm, he's at a point where he's spawning "chunkY"-blocks in exactly the same position ;D There is a lot more steps he's going to walk through working on that project before he actually can start optimizing anything.
btw: "greedy meshing" is the right keyword to look up for optimizing $$anonymous$$ecraft style world meshes
$$anonymous$$y advice from the experiences I gathered so far (e.g. I implemented the TransVoxel algorithm in C# lately) is to take your time and truely understand what you are doing because everything else will very likely end up in a giant, inperformant mess at some point forcing you to refactor and rewrite a lot of code.