【发布时间】:2013-07-17 06:23:16
【问题描述】:
我刚开始使用世界生成,我一直在到处寻找关于 perlin noise 的教程,但遗憾的是在 Google 上找不到很多。 最后几天我遵循了一个教程,但我无法让我的代码工作。
这是我的 Java 方法。
private static double[][] createNoise(int xn, int yn, int sps) {
int m = yn * sps;
int n = xn * sps;
double[][] u = new double[yn + 1][];
double[][] v = new double[yn + 1][];
double[][] x = new double[m][];
double[][] y = new double[m][];
double[][] z = new double[m][];
for (int i = 0; i < m; i++) {
x[i] = new double[n];
y[i] = new double[n];
z[i] = new double[n];
}
for (int i = 0; i < yn + 1; i++) {
u[i] = new double[xn + 1];
v[i] = new double[xn + 1];
}
for (int i = 0; i < xn + 1; i++) {
for (int j = 0; j < yn + 1; j++) {
u[i][j] = nextRandom();
v[i][j] = nextRandom();
}
}
double hx = xn / (n - 1);
double hy = yn / (m - 1);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
x[i][j] = hx * j;
y[i][j] = hy * i;
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int xc = (int)x[i][j];
int yc = (int)y[i][j];
if (x[i][j] % 1 == 0 && x[i][j] != 0 ) xc = xc - 1;
if (y[i][j] % 1 == 0 && y[i][j] != 0 ) yc = yc - 1;
double xr = x[i][j] - xc;
double yr = y[i][j] - yc;
double s11[] = {-xr, -yr};
double s21[] = {-xr, 1 - yr};
double s22[] = {1 - xr, 1 - yr};
double s12[] = {1 - xr, -yr};
double q11 = s11[0] * u[yc][xc] + s11[1] * v[yc][xc];
double q21 = s21[0] * u[yc + 1][xc] + s21[1] * v[yc + 1][xc];
double q22 = s22[0] * u[yc + 1][xc + 1] + s22[1] * v[yc + 1][xc + 1];
double q12 = s12[0] * u[yc][xc + 1] + s12[1] * v[yc][xc + 1];
z[i][j] = lerp(x[i][j], y[i][j], xc, xc + 1, yc, yc + 1, q11, q12, q21, q22);
}
}
return z;
}
该方法返回的高度图是这样的
如您所见,第一行/列正在运行,但之后算法似乎失败了。 我确定方法
nextRandom();
返回一个介于 -1 和 1 之间的浮点值。
非常感谢!
【问题讨论】:
-
我对柏林噪声一无所知,但您的问题之一是:hx = xn / (n - 1);它几乎总是给你0,因为在java中这个语句被视为两个整数的除法,结果是一个整数,然后转换为double
-
好了,谢谢您,先生,您拯救了这一天!
-
如果没有完整的源代码(例如 lerp 函数),我不能确定,但我是否正确地说每次运行时都会得到不同的噪音(nextRandom() 是对我来说是红旗)。 perlin 噪声最有用的特性是它是可重现的。即您可以随时获得 (x,y) 的特定噪声值;只知道一些播种信息和 (x,y) 坐标。这对于一次性创建整个世界显然不可行的无限世界特别有用。
标签: java algorithm noise perlin-noise