5
\$\begingroup\$

im working on a voxel based game in unity. the terrain(sphere-->planet) should be out of voxels and at first i built a minecraft like voxel plugin for unity. this means that i had a sphere out of cubes, but as you can imagine, a sphere out of cubes just doesn't look good :P (i made a level array which stored the material at [x,y,z]. --> so when "1" stands for stone, it means that level[x,y,z] = 1; was stone. but then i decided to use the marching cubes algorithm for my voxel planet. so i learned the marching cubes algorithm and i realised that now i must have a density function, and not a level array with material information.

my density function looks like this:

x * x + y * y + z * z - rad - (noise.FractalNoise3D (x, y, z, oct, frec, amp) * scale);

The noise is made by a simplex noise generator script. so far so good. i get a good sphere rendered with a little bit of noise. but when i try to edit the sphere (terrain editing) i run into problems.

i made a function which gets the collision coordinates(x,y,z) of the mouse and the sphere, and changes the density in the level array at these coordinates.:

void dig(){ Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit;

    if (Physics.Raycast (ray, out hit)) {
        Debug.Log ("Dig...");
        Debug.DrawLine(ray.origin,ray.origin+( ray.direction*hit.distance), Color.green,2);
        editTerrain(hit);
    }
}



void editTerrain(RaycastHit hit){
    int xEn = (int) hit.point.x;
    int yEn = (int) hit.point.y;
    int zEn = (int) hit.point.z;


    level [xEn, yEn, zEn] += 1000;


    mesh = MarchingCubes.CreateMesh (level);
    mesh.uv = new Vector2[mesh.vertices.Length];
    mesh.RecalculateNormals ();
    GetComponent<MeshFilter> ().mesh = mesh;
    GetComponent<MeshCollider>().sharedMesh=mesh;
}

my problems/questions now:

-is the density function alone enough for my level array? did i understand terrain creation right so far?

-when i try to edit the terrain (add something to the density at levelArray[x,y,z], it just flats the surface, but doesn't dig holes.

-when i want to add materials to my voxel planet (stone, dirt, sand, etc...), can i make another array, which holds the material data at [x,y,z]? are there better possibilities?

-i also realised that when i turn my sphere in the unity editor, my colission detecten gets displaced. like when i want to edit the top of the sphere, the bottom of the sphere gets changed...

-btw...i know i didn't apply chunks to my voxel planet yet...this comes later...

i hope anybody can help me because i don't know what to do.

\$\endgroup\$
  • 3
    \$\begingroup\$ You have a lot of questions in here and while I think they should all be asked and answered I would suggest maybe asking your first question on its own. 'Why is it when you alter the density values it seems to lower an entire region instead of dig a hole?' as the first one.. and then let the other questions (how to add materials) happen later down the road or outside of the context of the initial question. \$\endgroup\$ – James Jan 21 '15 at 0:02
  • \$\begingroup\$ How are you setting your density? It looks like you're storing an int value, but your editTerrain function only adds volume, to dig, you'd need to remove volume. Making materials using marching cubes is non-trivial - generating the mesh starts requiring complicated blends, if you require more than 4 materials, you need to work out a material blending solution beyond RGBA filtering. As your marching cubes are offset from your scalar data, you may need 8 textures per cube. \$\endgroup\$ – salmonmoose Jan 21 '15 at 0:15
  • \$\begingroup\$ FYI be careful using simplex noise, it's patented. \$\endgroup\$ – Soapy Jan 21 '15 at 10:08
  • \$\begingroup\$ i set my density through this function: xx+yy+z*z -r. i think i solved the terrain edit part, thank you :) i just played with the density values in the level array, no prob anymore :) no to the materials: can i use another array to store "material" data for stone, dirt...? \$\endgroup\$ – David Jelen Jan 21 '15 at 23:04
  • \$\begingroup\$ Found this awesome article about marching cubes a while ago, hope it helps. \$\endgroup\$ – newton1212 Jun 6 '15 at 12:37
2
\$\begingroup\$

marching cubes deals with voxel densities between -1 and 1 and alters the geometry of each cube based on its own density compared to the densities around it. this mean that it can actually put faces(triangles) within sections of space that contain less than zero density. In such cases trying to change the value at that section (using a FloorToInt function or whatever) with be like setting zero to zero. it's easy to deal with with simple cubes, but when you get into marching cubes and dual contouring you need to start working with normals and/or ray direction.

If your code thinks it has hit something but when you run a check it's actually hit a zero (or -1 in marching cubes) weight cube you need to tell it to keep looking to find what it was supposed to have hit.

you can mess with the target setting of marching cubes. you can also treat space in 27s instead of 1s by treating the hit point as the center and looping through -1 to +1 in x,y,z and setting them all to -1. This will make certain there is clear hole where you are digging. Otherwise the surfaces around it might all blend together and never reveal the next level down in your digging.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.