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; } }