[XNA 4.0] Terrain Generation with 3D Perlin Noise?

Started by
0 comments, last by PolyVox 12 years, 9 months ago
Hi guys!
I'm working on a game that makes use of Minecraft-style terrain (yes, another one :D).

I've got 2D Perlin Noise working perfectly, and I'm ready to move on. Many of the other projects I've seen or read about note the use of 3D Perlin Noise for terrain generation, so I've spent the day googling for some good documents on 3D Noise. Normally, for terrain you'd stick to 2D, but one of the problems with that is that it only creates a 'top' layer, it doesn't allow creation of Cave systems, overhangs, and other more impressive procedural structures - which is where 3D Noise comes in.

So far I've managed to implement a simple noise generator, thanks to this document (the 3D Simplex Noise example). But now I am left with a problem, how exactly do I convert this into terrain? With 2D noise, I simply took the resulting value as the heigh and fitted it within a corresponding 'level', but I'm pretty sure this will not work when working with 3D (mainly due to the fact that the noise already has a height position). I noticed a post on Notch's blog regarding this:

So I switched the system over into a similar system based off 3D Perlin noise. Instead of sampling the “ground height”, I treated the noise value as the “density”, where anything lower than 0 would be air, and anything higher than or equal to 0 would be ground. To make sure the bottom layer is solid and the top isn’t, I just add the height (offset by the water level) to the sampled result.[/quote]

So, following this information, I did the same. Basically, any noise value greater than or equal to 0 is set to a filled block, anything else is left empty, and below is the result.

1zq94dv.png


Now, this may just be me, but that doesn't look right. Does anyone have an idea how I go around fixing this? Heres the code I'm using to fill the blocks in:


public void generate3DHeightmap()
{
for(int i = 0; i < width; i ++)
for(int j = 0; j < height; j ++)
for(int k = 0; k < length; k ++)
{
double noise = perlinNoise3d.noise(i, j, k);
if(noise >= 0)
blocks[i, j, k].setType(Blocks.grass);
}


P.S. I have not attempted the 'offset by the height' method yet, but I'm still pretty sure that it should have some form of order even without this addition.

Thanks!!
Matt.
Advertisement
It probably just because the noise is too high frequency. Try dividing i,j and k by some (floating point) value:

[font="Courier New"]double noise = perlinNoise3d.noise(i / 10.0f, j / 10.0f, k / 10.0f);[/font]

I don't know exactly what value you need to divide by though - you'll need to experiment. Also, you might be interested in these links:

http://www.gamedev.net/blog/33/entry-2225133-minecraft/
http://www.gamedev.net/blog/33/entry-2227887-more-on-minecraft-type-world-gen/
http://www.gamedev.net/blog/33/entry-2249106-more-procedural-voxel-world-generation/

This topic is closed to new replies.

Advertisement