Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cliffs terrain generation in minecraft-like game

I want to generate something like this: cliffs
I use Perlin Noise with sharp curve, my code produces those cliffs: my cliffs .

    for (int x = 0; x < sizeX; x++)
    {
        for (int z = 0; z < sizeZ; z++)
        {
            int floorY = map.GetMaxYNotWater(x, z);
            float n = hillsNoise.Noise(x, z);
            int hillY = (int)(curveHills.Evaluate(n) * 80f);
            if (hillY > floorY + 5)
            {
                for (int y = hillY; y > floorY; y--)
                {
                    map.SetBlock(GetBlock(y), new Vector3i(x, y, z));
                }
            }
        }
    }

How can I "cut" them to make hanging things?

I tried to do it like this with additional curve:

    for (int x = 0; x < sizeX; x++)
    {
        for (int z = 0; z < sizeZ; z++)
        {
            int floorY = map.GetMaxYNotWater(x, z);
            float n = hillsNoise.Noise(x, z);
            int hillY = (int)(curveHills.Evaluate(n) * 80f);
            if (hillY > floorY + 5)
            {
                int c = 0;
                int max = hillY - floorY;
                max = (int)(max * curveHillsFull.Evaluate(n)) + 1;
                for (int y = hillY; y > floorY && c < max; y--, c++)
                {
                    map.SetBlock(GetBlock(y), new Vector3i(x, y, z));
                }
            }
        }
    }

But it produces flying islands. Flying islands So what can I do to achieve the first screenshot results?

like image 354
Vlad Avatar asked Jun 25 '14 19:06

Vlad


People also ask

How does Minecraft terrain generate?

Minecraft terrain, like most 3D terrain in video games, is entirely based on noise. When you begin the game, a random 64 bit number called a Seed is generated (or chosen by the player), and this seed is used to generated the world.

When did Minecraft world generation change?

The Update that Changed the World is the name for Java Edition version 1.7. 2, a major update released on October 25, 2013.

How does procedural generation work?

In computing, procedural generation is a method of creating data algorithmically as opposed to manually, typically through a combination of human-generated assets and algorithms coupled with computer-generated randomness and processing power. In computer graphics, it is commonly used to create textures and 3D models.

Does Minecraft use Perlin or simplex noise?

Minecraft is specifically using Perlin noise calculations, like the kind you'd use to create a rough-looking texture for a 3D model. It starts out on a very broad level, painting a basic topographical map, and adds "noise" through finer terrain details like lakes, shrubbery and animals.


1 Answers

I can't say how Minecraft does it, but from my own experience with voxel terrain, the best way to approach it is to think of the voxel grid as something like a cloud: each voxel has a density, and when that density is high enough, it becomes a 'visible' part of the cloud and you fill the voxel.

So rather than calculating the min and max Y levels, work on calculating the density value, something like this:

    for (int x = 0; x < sizeX; x++)
    {
        for (int y = 0; y > sizeY; y--)
        {
            for (int z = 0; z < sizeZ; z++)
            {
                //This means less density at higher elevations, great for turning 
                //a uniform cloud into a terrain. Multiply this for flatter worlds
                float flatWorldDensity = y;

                //This calculates 3d Noise: you will probably have to tweak this 
                //heavily. Multiplying input co-ordinates will allow you to scale 
                //terrain features, while multiplying the noise itself will make the 
                //features stronger and more or less apparent
                float xNoise = hillsNoise.Noise(x, y);
                float yNoise = hillsNoise.Noise(x, z);
                float zNoise = hillsNoise.Noise(y, z);
                float 3dNoiseDensity = (xNoise + yNoise + zNoise) / 3;

                //And this adds them together. Change the constant "1" to get more or
                //less land material. Simple!
                float ActualDensity = flatWorldDensity + 3dNoiseDensity;
                if (ActualDensity > 1)
                {
                    map.SetBlock(GetBlock(y), new Vector3i(x, y, z));
                }
            }
        }
    }
like image 54
Quasar Avatar answered Sep 24 '22 07:09

Quasar