I am new to using JME and have been doing a lot of reading into the basics, and specifically terrain and custom meshes. What I am looking to do is re-create something like this:
My first thought was having a water texture covering the whole map at 0,0,0 and then using a terrain that uses a heightmap to have the slope and then leading to the grass… however the terrain also has to be editable (only be able to add to it) which then leads me to custom meshes? Then how would I go about the slope? Make a custom vertex? How do I get the textures to join?
So, I’ve had a play around and i’ve been able to create my own custom mesh (with squares) and I have code set up that can generate a grid of the squares, however I want to create an irregular island shape. Say…
I don’t see it very practical to create shapes that match this. I’m not sure if custom meshes is the way to go? I need the terrain to be able to be added to. For example, if they were to place an object on the water’s edge, the island would expand by 1 block.
Research terrain generation algorythms. Perlin noise is what’s called “organic noise” in that instead of it giving random numbers that are vastly different (which would result in a very spikey terrain), it slowly moves from one to another in more of a curve.
Using two-dimensional perlin (or any organic noise such as simplex) noise, you would query the algorythm in an x,z pattern, and use the resulting number as the height.
Using your custom mesh generator, give each vertex the x,z co-ordinates you gave the algorythm, and set the Y co-ordinate to the given result.
You can then create meshes side-by-side that will match perfectly (cough normals at edges cough).
For caves, the fastest way I have come across is posterization. Use another instance of the noise generator with a different seed (or even offset the coordinates sufficiently so that it “fakes” it) and blend the results together.
Thanks for your reply, I appreciate it and I learned a few useful things! However, the island I am creating is completely flat (with no lakes/rivers/etc) apart from the edges that drop into the water. See the image above.
I’ve looked into using a circular mask over the noise, however that also leads me to having breaks in the island itself. I have done quite a bit of searching, but can’t find anything that quite suits my needs.
The nice thing about noise based algorithms is that you can (generally) go to any part of the world and generate just that section from scratch.
However, if you are going to be generating your land all at once then there are other fractal subdivision algorithms that can work better/differently.
For example, take a quad… divide each side in half and displace it randomly against that side’s normal. Now you have an odd 8 sided figure. Do it to each of those sides… and again… and again… eventually you will have something that looks island shaped.
Adding to it can be done similarly by slicing into the ring, adding some long sides and subdividing them the same way.
Yeah there are loads of ways. A simple way is to use the dist function of the vector class. If you have a 33x33 piece of land, use the distance from the center (16,16) and normalize it to reduce the noise.
// pseudo code.
int size = 33; // the size of your mesh in vertices.
Vector2f center = new Vector2f(16, 16);
for (int x = 0; x < size; x++) {
for (int z = 0; z < size; z++) {
Vector2f vertex = new Vector2f(x, z);
float dist = FastMath.abs(vertex.distance(size));
dist = 1.0f - (size.x / dist); // normalize the result.
float noise = noiseGen.getNoise(x, z) * dist;
Vector3f vertexPos = new Vector2f(x, noise, z);
}
}
Hopefully you can “see” the code, but the dist function makes a “circle” from the center and reduces the noise depending on how far it is. You can apply some kind of sine function to it for a smoother effect.
Paul talks sense. But to answer your question, the noise gives a normalized output. You must multiply it with a desired height to get some altitude. Multiplying the X and z plane by say .1 of the coordinate will reduce change and stretch the noise out, and multiplying height gives depth of change to your mesh.
The only issue now is making the island bigger (more vertices), as if I make it too big I get an OutOfMemory exception. Going from there, I would have to add some sort of character, split the island into chunks, then only render the chunks that the character can view. Right?