I've decided to code Perlin noise generator in Java. It works pretty well, I just want to know If I am doing everything right and if it is a valid implementation!
PS : The metaVector2f
and metaVector2i
are just 2D vector classes
public float[][] generate(long seed, metaVector2i size, metaVector2i gridSize) {
Random rand = new Random(seed);
metaVector2f[][] gvectors = new metaVector2f[gridSize.x][gridSize.y];
for (int y = 0; y < gridSize.y; y++)
for (int x = 0; x < gridSize.x; x++)
gvectors[x][y] = new metaVector2f(rand.nextFloat(),rand.nextFloat());
float[][] data = new float[size.x][size.y];
for (int y = 0; y < size.y; y++)
for (int x = 0; x < size.x; x++) {
data[x][y] = perlinPoint(new metaVector2f(x/(float)(size.x/gridSize.x),y/(float)(size.y/gridSize.y)), gvectors);
}
return data;
}
private float perlinPoint(metaVector2f position, metaVector2f[][] gvectors) {
int x0 = (int)position.x;
int y0 = (int)position.y;
int x1 = (int)position.x+1;
int y1 = (int)position.y+1;
float dx0 = position.x-x0;
float dy0 = position.y-y0;
float dx1 = position.x-x1;
float dy1 = position.y-y1;
float h1 = dotProduct(new metaVector2f(dx0, dy0), gvectors[x0%gvectors.length][y0%gvectors[0].length]);
float h2 = dotProduct(new metaVector2f(dx1, dy0), gvectors[x1%gvectors.length][y0%gvectors[0].length]);
float fin1 = lerp(h1, h2, dx0);
float v1 = dotProduct(new metaVector2f(dx0, dy1), gvectors[x0%gvectors.length][y1%gvectors[0].length]);
float v2 = dotProduct(new metaVector2f(dx1, dy1), gvectors[x1%gvectors.length][y1%gvectors[0].length]);
float fin2 = lerp(v1, v2, dx0);
return lerp(fin1,fin2,dy0);
}
private float lerp(float x, float y, float t) {
return (1.0f - t)*x + t*y;
}
private float dotProduct(metaVector2f vec, metaVector2f grad) {
return vec.x*grad.x+vec.y*grad.y;
}
Here is the output (value/2+0.5f) :
1
-
\$\begingroup\$ That output doesn't look right. Generally the x/y coordinates within each square are passed through a smoothstep function, otherwise you get those artifacts around the edges of each square (can clearly see a 10x10 grid here, it shouldn't be that apparent). This article is good if you haven't seen it: flafla2.github.io/2014/08/09/perlinnoise.html \$\endgroup\$user11536834– user115368342019年07月24日 23:12:18 +00:00Commented Jul 24, 2019 at 23:12
1 Answer 1
Consider warmwaffle's code at GitHub (re: https://github.com/warmwaffles/Noise). The one difference I see between the two solutions is how the 'metaVector2f's are created. Your code is using non-repeatable random numbers; whereas, the other uses a mathematical calculation which includes prime numbers and bit shifting operations. The latter would produce a repeatable solution with the same seed versus yours. This may be worth something if you're testing or troubleshooting elsewhere.