我的perlin噪声实现似乎有问题......每当我输入负坐标时,perlin噪声都不会平滑。我发现有些人和我一样有同样的问题,但除了我发现的this文章之外,没有人真的有解决方案。我在解决方案中工作,但这一代并没有修复。 (我可能做错了)这是我在Java中的Perlin Noise实现:
public B15(long seed, int f) {
this.seed = seed;
this.f = f;
rand = new Random();
}
public static double[][] getTerrainFromChunks(int cX, int cY, int octaves, double[] amp, int[] freq, long seed) {
double[][] noise = new double[16][16];
for(int z = 0; z < octaves; z++) {
B15 oct = new B15(seed, freq[z]);
for(int y = 0; y < 16; y++) {
for(int x = 0; x < 16; x++) {
noise[x][y] = noise[x][y] + (amp[z] * oct.getNoiseLevelAtPosition((cX * 16) + x, (cY * 16) + y));
}
}
}
return noise;
}
public double getNoiseLevelAtPosition(int x, int y) {
int xmin = (int) (double) x / f;
int xmax = xmin + 1;
int ymin = (int) (double) y / f;
int ymax = ymin + 1;
return cosineInterpolate(
cosineInterpolate((float) getRandomAtPosition(xmin, ymin),
(float) getRandomAtPosition(xmax, ymin), (float) (x - xmin * f) / f),
cosineInterpolate((float) getRandomAtPosition(xmin, ymax),
(float) getRandomAtPosition(xmax, ymax), (float) (x - xmin * f) / f),
((float) y - (float) ymin * (float) f) / (float) f);
}
private float cosineInterpolate(float a, float b, float x) {
float f = (float) ((1f - Math.cos(x * Math.PI)) * .5f);
return a * (1f - f) + b * f;
}
private double getRandomAtPosition(int x, int y) {
rand.setSeed((long) (10000 * (Math.sin(x) + Math.cos(y) + Math.tan(seed))));
return rand.nextDouble();
}
我在明显的解决方案中工作如下:
public double getNoiseLevelAtPosition(int x, int y) {
int xmin = (int) (double) x / f;
int xmax = xmin + 1;
int ymin = (int) (double) y / f;
int ymax = ymin + 1;
x -= xmin; |
y -= ymin; | - New Code which
if(x < 0) { x += 1; xmax = (xmax + 255) & 255; } | I hoped would fix
if(y < 0) { y += 1; ymax = (ymax + 255) & 255; } | the issue
return cosineInterpolate(
cosineInterpolate((float) getRandomAtPosition(xmin, ymin),
(float) getRandomAtPosition(xmax, ymin), (float) (x - xmin * f) / f),
cosineInterpolate((float) getRandomAtPosition(xmin, ymax),
(float) getRandomAtPosition(xmax, ymax), (float) (x - xmin * f) / f),
((float) y - (float) ymin * (float) f) / (float) f);
}
抱歉,我没有任何视觉图片,但上面的文章中有我的问题的图片,但它们是3维。如果它甚至可以解决,有没有人对如何解决这个问题有任何想法?谢谢!
编辑:这是解决方案的更新代码,但它只是在负x轴上反映了这一代...(实际上在整个x轴上包括正面和负面)
public B15(long seed, int f) {
this.seed = seed;
this.f = f;
rand = new Random();
}
public static double[][] getTerrainFromChunks(int cX, int cY, int octaves, double[] amp, int[] freq, long seed) {
double[][] noise = new double[16][16];
for(int z = 0; z < octaves; z++) {
B15 oct = new B15(seed, freq[z]);
for(int y = 0; y < 16; y++) {
for(int x = 0; x < 16; x++) {
noise[x][y] = noise[x][y] + (amp[z] * oct.getNoiseLevelAtPosition((cX * 16) + x, (cY * 16) + y));
}
}
}
return noise;
}
public double getNoiseLevelAtPosition(int x, int y) {
int xmin = (int) Math.floor((double) x / f);
int xmax = xmin + 1;
int ymin = (int) Math.floor((double) y / f);
int ymax = ymin + 1;
return cosineInterpolate(
cosineInterpolate((float) getRandomAtPosition(xmin, ymin),
(float) getRandomAtPosition(xmax, ymin), (float) (x - xmin * f) / f),
cosineInterpolate((float) getRandomAtPosition(xmin, ymax),
(float) getRandomAtPosition(xmax, ymax), (float) (x - xmin * f) / f),
((float) y - (float) ymin * (float) f) / (float) f);
}
private float cosineInterpolate(float a, float b, float x) {
float f = (float) ((1f - Math.cos(x * Math.PI)) * .5f);
return a * (1f - f) + b * f;
}
private double getRandomAtPosition(int x, int y) {
rand.setSeed((long) (10000 * (Math.sin(x) + Math.cos(y) + Math.tan(seed))));
return rand.nextDouble();
}