While noise is unwanted in many occasions, it is a great tool for procedural generation and has many uses. In this recipe, we'll explore jMonkeyEngine's FractalSum
class and generate an image based on the output. This can be used as a heightmap for a terrain, but we are not limited by that. With some tweaking, we could get a basis to cover a forest or city.
This recipe relies on a way to output an image. Either use your own method to do this or refer to the The ImageGenerator class section in Appendix, Information Fragments, which provides an example of how to do it.
To generate a heightmap, perform the following steps:
NoiseMapGenerator
.FractalSum
instance and store it in a field called fractalSum
.generateNoiseMap
that takes an integer parameter called size
, a float parameter called frequency
, and an integer parameter called octaves
as inputs.fractalSum
with some of the values and set the amplitude to 0.5f
as follows:fractalSum.setFrequency(frequency); fractalSum.setAmplitude(0.5f); fractalSum.setOctaves(octaves);
terrain
. Its dimension should be [size] x [size].for
loop statement and parse through the size of both dimensions. Inside the loop, we get the value from fractalSum
, which is based on your x and y coordinates; add 0.5f
to the value. Clamp it to get a value between 0f
and 1f
and set the value in the terrain array as follows:for(int y = 0; y < size; y++){ for(int x = 0; x < size; x++){ float value = fractalSum.value(x, 0, y) + 0.5f; value = FastMath.clamp(value, 0f, 1f); terrain[x][y] = value; } }
ImageGenerator
class to create the PNG image for us as follows:ImageGenerator.generateImage(terrain);
With this simple implementation, and by using the supplied ImageGenerator
class, we have the basics for a heightmap. We can see the result in our Projects
folder under assets/Textures/heightmap.png
. It's an image that shifts smoothly between bright and dark areas; here, bright areas represent a high terrain and dark areas, a low terrain. Bright pixels have values that are close to 1, whereas dark pixels have values close to 0. Normally, noise outputs values between -1 and 1. This is why we change the amplitude to 0.5f so that it yields a range between -0.5 and 0.5, and then we add 0.5 to the result.
A noticeable problem is that no matter how much we change the speed and frequency of the noise, the same kind of rolling hills landscape will appear, only in different scales. By changing the octaves' value, we will generate noise in several iterations with decreasing amplitude. The value of each pixel for each iteration is multiplied with the previous one. The result is called fractal noise. Using octaves is a way of adding detail by iterating over the result with different frequencies. For each iteration, the frequency is doubled and the amplitude is halved.
Frequency can be thought of as a scale value where a higher frequency will generate more and smaller features. Having a higher frequency on its own will make peaks and valleys occur more frequently.
A normalization process is not strictly needed for a heightmap, unless we want to save it as an image. Also, if we were generating a large number of heightmaps (for example, during the runtime for a game), we would not want to normalize the terrain based on a particular heightmap's minimum and maximum values or we would end up with very similar and hilly landscapes.
Now that we have generated a heightmap and exported it to an image, we can actually use it as a base in Terrain Editor. The process is similar to the one where we created a terrain for our scene in Chapter 1, SDK Game Development Hub.
After creating a new scene (by all means, we can use an existing scene as well) and opening it, we can right-click on the main node in the SceneExplorer window and select Add Spatial.. and then select Terrain...
It's important that we select the same total size as that of the pixels of our image. Then, in the Heightmap screen, we choose Image Based from the HeightMap drop-down menu and select our image.
The Roughness slider will define how much the heightmap will be smoothed out before it is added. A higher smoothness will remove finer details, and this is a must if we want to have characters that will run or drive on top of it.
The Height Scale option will define the maximum altitude that the heightmap can have and scale it accordingly.
3.142.40.32