4
\$\begingroup\$

I want to create a 3D block-based infinite world.

For any block, I want to be able to compute its block type.

3D perlin noise is the usual building block of such a world. If you ask the 3D noise function the value for a 3D point, it'll give you a value between -1 and 1.

How do you turn this number into a block type?

I want blocks on the surface to be turf, and different minerals to have different probabilities based on depth. I want sprawling caves and caverns and lava flows but not small ones. And so on.

So how do you turn noise into block types into a coherent subterranean world? Particularly how do you make things like coal appear in seams and crystals only appear in caves and any other rules that can be invented that make the type of a block dependent upon its neighbours?

And how to do this efficiently, in an oracle function rather than by having to create large 3D arrays to store the decided outcomes of some terraforming?

\$\endgroup\$
2
  • 2
    \$\begingroup\$ It gives you a value between -1 and 1, or 0 and 1. Pi has nothing to do with it. A common strategy is to map the return range to a density and assign your block types densities based on their material type. \$\endgroup\$
    – House
    Jul 18, 2013 at 15:26
  • \$\begingroup\$ @Byte56 yes I see now buried in the perlin noise func I was borrowing that its scaled. Don't know why they did that. Anyway, my question is about the block type densities themselves and how to have things like caves rather than random 1x1x1 voids and to avoid it actually feeling random. \$\endgroup\$
    – Will
    Jul 18, 2013 at 15:33

1 Answer 1

6
\$\begingroup\$

Use many layers of perlin noise (or better simplex noise) differing in scale, range and dimensionality. There is a nice post on gamedev.net. And its continuation.

For the basic shape, use a combination of 2d and 3d noise. Using just the 3d part wouldn't result in noticeable distinction between a solid ground and free air. Using only the 2d part wouldn't allow for overhangs like any 2d heightmap. Therefore combine both.

Then use additional layers of noise to define block types. For example, use 2d noise for area properties like biomes, which might result in defferent ground types.

For special features like minerals in the ground use 3d noise with a very high threshold and clamp the range. Say, you want ores to be found in the range of 5 to 20 blocks from down, sample this noise only if the current block is of this height. Then only if the noise exceeds say 0.9, place ore instead of stone.

Moreover, calculating all blocks directly and independently is a good aim but wasn't practically for me. At least for forms that grow over time in nature. For this it is useful to first generate the basic terrain shape and iterate over the world to modify it based on adjacent blocks. For example you need that to cover an area with a 1 block thick layer of grass blocks.

It may also help you to look over my world generation code at Github. Here is an example of how my procedural generated world looks like.

world generated by my world generator

\$\endgroup\$
2
  • \$\begingroup\$ Your link is dead. \$\endgroup\$
    – Timtech
    Aug 24, 2013 at 21:27
  • \$\begingroup\$ @Timtech Thanks for pointing that out. The directory structure in my repository changed, thus the link didn't anymore pointed to where the file is. But I don't know if Github allows me to link to a specific historic version of a file. Anyhow, I corrected the link of course. \$\endgroup\$
    – danijar
    Aug 24, 2013 at 21:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .