Created
November 3, 2016 19:37
-
-
Save hidde-vb/436bc01785e28091483b5463aafddbaa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.magma.game.noise; | |
import java.util.Random; | |
public class NoiseGenerator { | |
private Random rdm; | |
public NoiseGenerator(){ | |
this(0); | |
} | |
public NoiseGenerator(int seed){ | |
rdm = new Random(seed); | |
} | |
public float[][] noise(int width, int height){ | |
float[][] noise = new float[width][height]; | |
for(int x=0; x<width; x++){ | |
for(int y=0; y<height; y++){ | |
noise[x][y] = (float)rdm.nextDouble()%1; | |
} | |
} | |
return noise; | |
} | |
public float[][] perlinNoise(float[][] base, int octaves, float persistence){ | |
int width = base.length; | |
int height = base[0].length; | |
float amplitude = 1.0f; | |
float totalAmplitude = 0.0f; | |
float[][] noise = new float[width][height]; | |
float[][][] layers = new float[octaves][][]; | |
// Generate layers of smooth noise | |
for(int i=0; i<octaves; i++){ | |
layers[i] = smoothNoise(base, i); | |
} | |
// Blend layers | |
for(int i=octaves-1; i>=0; i--){ | |
amplitude *= persistence; | |
totalAmplitude += amplitude; | |
for(int x=0; x<width; x++){ | |
for(int y=0; y<height; y++) { | |
noise[x][y] += layers[i][x][y]*amplitude; | |
} | |
} | |
} | |
// Normalise | |
for(int x=0; x<width; x++) { | |
for (int y = 0; y<height; y++) { | |
noise[x][y] /= totalAmplitude; | |
} | |
} | |
return noise; | |
} | |
private float[][] smoothNoise(float[][] base, int octave){ | |
int width = base.length; | |
int height = base[0].length; | |
float[][] noise = new float[width][height]; | |
// octaves wavelength & frequency | |
int period = 1 << octave; // equals to 2^octave+1 | |
float frequency = 1.0f / period; | |
for(int x=0; x<width; x++){ | |
// Horizontal sampling | |
int x0 = (x/period) * period; | |
int x1 = (x0+period) % height; | |
float xBlend = (x-x0) * frequency; | |
for(int y=0; y<height; y++){ | |
// Vertical sampling | |
int y0 = (y/period) * period; | |
int y1 = (y0+period) % height; | |
float yBlend = (y-y0) * frequency; | |
// Blending | |
float top = interpolate(base[x0][y0],base[x1][y0],xBlend); | |
float bottom = interpolate(base[x0][y1],base[x1][y1],xBlend); | |
noise[x][y] = interpolate(top, bottom , yBlend); | |
} | |
} | |
return noise; | |
} | |
private float interpolate(float a, float b, float alpha){ | |
return a * (1-alpha) + alpha*b; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment