Well, I finally got round to testing out the noise algorithms again. And this time in Java.
I grabbed OpenSimplexNoise class and had to add my own functions to it so that I could use ‘octaves’ and ‘persistence’ values to add roughness to it. The extra functions which handle 2D and 3D noise are:
public double OctavePerlin2(double x, double y, int octaves, double persistence) {
double total = 0;
double frequency = 1;
double amplitude = 1;
double maxValue = 0; // Used for normalizing result to 0.0 - 1.0
for(int i=0;i<octaves;i++) {
total += eval(x * frequency, y * frequency) * amplitude;
maxValue += amplitude;
amplitude *= persistence;
frequency *= 2;
}
return total/maxValue;
}
public double OctavePerlin3(double x, double y, double z, int octaves, double persistence) {
double total = 0;
double frequency = 1;
double amplitude = 1;
double maxValue = 0; // Used for normalizing result to 0.0 - 1.0
for(int i=0;i<octaves;i++) {
total += eval(x * frequency, y * frequency, z * frequency) * amplitude;
maxValue += amplitude;
amplitude *= persistence;
frequency *= 2;
}
return total/maxValue;
}
Then I added a UI using Swing and got it all working including adding a water level.

[ADDED] And a better image:

All I need now is to break up the calculations into blocks and run each block on its own thread when I come to using this again.
The class which creates the bitmap:
public class BufferedImageNoise {
int w, h;
long seed;
double scale;
int off_x, off_y;
int octaves;
double persistence;
double water;
OpenSimplexNoise noise;
public BufferedImageNoise(int width, int height, long seed, double scale, int octaves, double persistence, double water) {
w = width; h = height;
this.seed = seed;
this.scale = scale;
this.octaves = octaves;
this.persistence = persistence;
this.water = water;
off_x = off_y = 0;
noise = new OpenSimplexNoise(seed);
}
public BufferedImage getImage() {
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
double value = noise.OctavePerlin2(x / scale, y / scale, octaves, persistence) + 1.3;
int rgb = value > water ? 0x010101 * (int)((value) * 127.5) : 0x000088;
image.setRGB(x, y, rgb);
}
}
return image;
}
}
