A Procedural Generation Experiment

Hello everyone, before I get to the meat of this thread, I just wanted to introduce myself. I believe this is my first thread (if not it may as well be), and I am just beginning to experiment with Unity.

Anyway, back to what this thread is actually about. I have been toying around with the idea of terrain being generated procedurally without using heightmaps. Heightmaps are great, but in my opinion I would much rather have overhangs, caves etc. So, I am starting to experiment with 3d noise to generate a scalar field. Taking this further, I will be using either marching cubes or marching tetrahedrons to produce a mesh in Unity (this is where I’ll have the most trouble since I just started with the engine).

The basis for this idea is to create an extremely large explorable world (the only limits being data storage). My plan is to have it loop back around at the extremes creating a “globe” one could theoretically circle.

I have decided against using Perlin Noise, opting instead for Simplex Noise (Also by Ken Perlin). I am going this way for the speed improvements, and it was actually quite easy to implement (using C#).

Thanks for listening to me rant, I mostly wanted to throw something up and see what others have to say.
I’ll update the thread when I have polygonization running.

Good luck, LibNoise may be helpful. My openly secret love has always been of anything procedural.

Ok, so I have gotten both the 3d noise and the marching cubes code written. As it stands, the resulting field would be about 50% solid and nowhere near traversable. All I’m looking for right now is an actual mesh to be generated and I will tune it to make a terrain later.

Here is the sample generator program I just scrapped together, all it is missing is how to actually render the triangles. If anyone has a simple way of doing this, let me know. I placed a comment in the logical place in the code.

There is a 10x10 grid of zones in the “world” and each zone is further divided into grid cells. The code is designed to allow for differing grid sizes to create a faster or slower render.

–EDIT–
I forgot to mention, each zone will currently be identical. Once I get it rendering, I will vary the zones according to their world coordinates with some form of hashing

–EDIT AGAIN–
So I ventured into Unity and got my DLL’s imported and my code stuck into a script. I believe I finally have it all set up, I just need to figure out the code for creating the mesh and adding triangles to it. If anyone could tell me what I’m looking for that would be awesome. If not, I’m sure I’ll figure it out eventually when I’m not so tired.

using UnityEngine;
using System.Collections;
using simplexNoise;
using marchingCubes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class NewBehaviourScript : MonoBehaviour {

	
	void Start () {
	//generate 100 zones in a 10x10 grid
            Zone[][] zones = new Zone[10][];
	
            for (int x = 0; x < 10; x++)
            {
                zones[x] = new Zone[10];
                for (int y = 0; y < 10; y++)
                {
                    zones[x][y] = new Zone(x, y);
                }
            }

            for (int x = 0; x < 10; x++)
            {
                zones[x] = new Zone[10];
                for (int y = 0; y < 10; y++)
                {
                    zones[x][y] = new Zone(x, y);
                    //this will display every zone, in the future, will only display what player can see
                    displayZone(zones[x][y], gridWidth);
                }
            }
	}
	static double gridWidth = .1;
  
	private static void displayZone(Zone zone, double frequency)
	{
		MarchingCubes.Triangle[] triangles;
		for (double z = frequency / 2.0 ; z < zone.height; z += frequency)
		{
			for (double y = frequency / 2.0; y < zone.length; y += frequency)
			{
				for (double x = frequency / 2.0; x < zone.width; x += frequency)
				{
					triangles = MarchingCubes.Polygonise(createGrid(x, y, z), 0.0);
					foreach (MarchingCubes.Triangle triangle in triangles)
					{
						
					}
				}
			}
		}
	}
	//create a cell on given center
	private static MarchingCubes.GridCell createGrid(double x, double y, double z)
	{
		MarchingCubes.XYZ[] corners = new MarchingCubes.XYZ[8];
		double[] cornerVals = new double[8];
		corners[0] = new MarchingCubes.XYZ(x - gridWidth/2.0, y + gridWidth/2.0, z - gridWidth/2.0);
		corners[1] = new MarchingCubes.XYZ(x + gridWidth/2.0, y + gridWidth/2.0, z - gridWidth/2.0);
		corners[2] = new MarchingCubes.XYZ(x + gridWidth/2.0, y - gridWidth/2.0, z - gridWidth/2.0);
		corners[3] = new MarchingCubes.XYZ(x - gridWidth/2.0, y - gridWidth/2.0, z - gridWidth/2.0);
		corners[4] = new MarchingCubes.XYZ(x - gridWidth/2.0, y + gridWidth/2.0, z + gridWidth/2.0);
		corners[5] = new MarchingCubes.XYZ(x + gridWidth/2.0, y + gridWidth/2.0, z + gridWidth/2.0);
		corners[6] = new MarchingCubes.XYZ(x + gridWidth/2.0, y - gridWidth/2.0, z + gridWidth/2.0);
		corners[7] = new MarchingCubes.XYZ(x - gridWidth/2.0, y - gridWidth/2.0, z + gridWidth/2.0);
		
		for (int i = 0; i < 8; i++)
		{
			cornerVals[i] = SimplexNoise.noise(corners[i].x, corners[i].y, corners[i].z);
		}

		MarchingCubes.GridCell cell = new MarchingCubes.GridCell(corners, cornerVals);
		return cell;
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}





    class Zone
    {
        int x;
        int y;
        public double width = 10.0;
        public double length = 10.0;
        public double height = 10.0;
        public Zone(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

jc_lvngstn did some work with terrain generation for a minecraft-clone starter pack. He was able to generate caves and overhangs, but of course the whole terrain is in cubes. However, you could generate vertex points instead and connect them

From the old After Playing Minecraft thread (page 4):

I have some experience with both noise types and actually find Perlin better for terrains, even without the speed gains in 3d however minute they are. That’s just my opinion though, it depends on what you think looks better.

In that same thread there’re scripts that “meshify” the data, not a bad place to start.

that would actually be a torus, not a sphere… just saying =p

Thanks everyone for your help, I found the part of the thread with the code that should help me. Oh, and you’re exactly right about the torus…I realized that last night, but I think I might just work it into the design. The only thing I would have to do is make one dimension shorter than the other so at the center of the world you wouldnt be stuck in between two layers (would be neat but I have no idea how I’d do that)