2
\$\begingroup\$

I was working on making procedurally generated terrain using normal cubish voxels (like minecraft) But then I read about marching cubes and decided to convert to using those. I managed to create a working marching cubes class and cycle through the densities and everything in it seemed to be working so I went on to work on actual terrain generation. I'm using XNA (C#) and a ported libnoise library to generate noise for the terrain generator. But instead of rendering smooth terrain I get a 64x64 chunk (I specified 64 but can change it) of seemingly random marching cubes using different triangles.

This is the code I'm using to generate a "chunk":

public MarchingCube[, ,] getTerrainChunk(int size, float dMultiplyer, int stepsize)
    {
        MarchingCube[, ,] temp = new MarchingCube[size / stepsize, size / stepsize, size / stepsize];
        for (int x = 0; x < size; x += stepsize)
        {
            for (int y = 0; y <size; y += stepsize)
            {
                for (int z = 0; z < size; z += stepsize)
                {
                    float[] densities = {(float)terrain.GetValue(x, y, z)*dMultiplyer, (float)terrain.GetValue(x, y+stepsize, z)*dMultiplyer, (float)terrain.GetValue(x+stepsize, y+stepsize, z)*dMultiplyer, (float)terrain.GetValue(x+stepsize, y, z)*dMultiplyer,
                    (float)terrain.GetValue(x,y,z+stepsize)*dMultiplyer,(float)terrain.GetValue(x,y+stepsize,z+stepsize)*dMultiplyer,(float)terrain.GetValue(x+stepsize,y+stepsize,z+stepsize)*dMultiplyer,(float)terrain.GetValue(x+stepsize,y,z+stepsize)*dMultiplyer };
                    Vector3[] corners = { new Vector3(x,y,z), new Vector3(x,y+stepsize,z),new Vector3(x+stepsize,y+stepsize,z),new Vector3(x+stepsize,y,z), new Vector3(x,y,z+stepsize), new Vector3(x,y+stepsize,z+stepsize),
                       new Vector3(x+stepsize,y+stepsize,z+stepsize), new Vector3(x+stepsize,y,z+stepsize)};
                    if (x == 0 && y == 0 && z == 0)
                    {
                        temp[x / stepsize, y / stepsize, z / stepsize] = new MarchingCube(densities, corners, device);
                    }
                    temp[x / stepsize, y / stepsize, z / stepsize] = new MarchingCube(densities, corners);
                }
            }
        }

(terrain is a Perlin Noise generated using libnoise)

I'm sure there's probably an easy solution to this but I've been drawing a blank for the past hour.

I'm just wondering if the problem is how I'm reading in the data from the noise or if I may be generating the noise wrong? Or maybe the noise is just not good for this kind of generation? If I'm reading it wrong does anyone know the right way?

the answers on google were somewhat ambiguous but I'm going to keep searching.

Thanks in advance!

\$\endgroup\$
3
  • \$\begingroup\$ Can you please phrase this as a question? \$\endgroup\$
    – indeed005
    Jul 12, 2012 at 2:29
  • \$\begingroup\$ Yes, sorry about that. \$\endgroup\$ Jul 12, 2012 at 2:37
  • \$\begingroup\$ Your question is kinda unrelated to your title. To make sure you are using the noise correctly I would first get a slice from the noise and push it to a bitmap (System.Drawing, really, that simple). You can then tweak that bit of the system without the rest of the system complicating it. \$\endgroup\$ Jul 12, 2012 at 7:48

1 Answer 1

1
\$\begingroup\$

I would try to decouple the problem into two distinct chunks: firstly, have a Marching Cubes algorithm that gets its data from an arbitrary 3d array; and second, have a function that will fill an array with values from noise.

Essentially, you're building an ad hoc 'unit testing' approach: on one side, you can fill in your array with 'easy' values by using specific functions of two variables (for instance, a constantly-sloping plane like f(x,y)=8x+10y+15z, or a smooth surface like f(x,y)=(x-100)^2+(y-100)^2+(z-100)^2 ) and confirm that Marching Cubes applied to level sets of these functions gives the results that you expect in those cases.

Meanwhile, on the other side you can write simpler rendering algorithms — for instance, just rendering a cube or even a particle for each value in the array that's within a certain range — and use those to visualize your noise function. Once you can confirm that both pieces of the puzzle are working well in 'toy' circumstances then you can make the optimizations of putting them together and eliminating the intermediate 3d array, but until you're certain that both are independently functional I would decouple them as much as possible.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the reply :) The marching cubes generated how I'd expect for the two functions you gave a couple other ones I tested, and when I changed from using marching cubes for terrain to normal cubes it came out actually looking like terrain. I had it place a cube anytime the noise value was greater than 0.2, which is the same thing I'm using as my iso value in the marching cubes. I noticed that the noise doesn't seem very smooth though, each time a random number of the corners of the cube has a negative value and the rest have positive resulting in a chunk of random looking marching cubes. \$\endgroup\$ Jul 13, 2012 at 17:41

You must log in to answer this question.

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