【发布时间】:2018-03-29 17:35:04
【问题描述】:
我的问题是我的柏林噪音在非常小的空间内非常明显地重复。 Here is an image of what it going on. 我知道这确实发生在所有柏林噪音的某个点之后,但它似乎几乎立即发生在我的身上。我相信这是由我非常糟糕的伪随机梯度生成器引起的,但我不确定。我的代码如下。
附带说明一下,我的 perlin 噪声似乎生成了非常小的值,介于 -.2 和正 .2 之间,我认为这也是由我的伪随机梯度生成器引起的。
如果有人对改进我的这部分代码有任何建议,请随时告诉我。现在任何想法都会有所帮助。
提前感谢大家!
public class Perlin {
int[] p = new int[255];
public Perlin() {
for(int i = 0; i < p.length; i++)
p[i] = i;
shuffle(p);
}
int grads[][] = {
{1,0},{0,1},{-1,0},{0,-1},
{1,1},{-1,1},{1,-1},{-1,-1}
};
public double perlin (double x, double y) {
int unitX = (int)Math.floor(x) & 255; // decide unit square
int unitY = (int)Math.floor(y) & 255; // decide unit square
double relX = x-Math.floor(x); // relative x position
double relY = y-Math.floor(y); // relative y position
// bad pseudorandom gradient -- what i think is causing the problems
int units = unitX+unitY;
int[] gradTL = grads[p[(units)]%(grads.length)];
int[] gradTR = grads[p[(units+1)]%(grads.length)];
int[] gradBL = grads[p[(units+1)]%(grads.length)];
int[] gradBR = grads[p[(units+2)]%(grads.length)];
// distance from edges to point, relative x and y inside the unit square
double[] vecTL = {relX,relY};
double[] vecTR = {relX-1,relY};
double[] vecBL = {relX,relY-1};
double[] vecBR = {relX-1,relY-1};
// dot product
double tl = dot(gradTL,vecTL);
double tr = dot(gradTR,vecTR);
double bl = dot(gradBL,vecBL);
double br = dot(gradBR,vecBR);
// perlins fade curve
double u = fade(relX);
double v = fade(relY);
// lerping the faded values
double x1 = lerp(tl,tr,u);
double y1 = lerp(bl,br,u);
// ditto
return lerp(x1,y1,v);
}
public double dot(int[] grad, double[] dist) {
return (grad[0]*dist[0]) + (grad[1]*dist[1]);
}
public double lerp(double start, double end, double rate){
return start+rate*(end-start);
}
public double fade(double t) {
return t*t*t*(t*(t*6-15)+10);
}
public void shuffle(int[] p) {
Random r = new Random();
for(int i = 0; i < p.length; i++) {
int n = r.nextInt(p.length - i);
// do swap thing
int place = p[i];
p[i] = p[i+n];
p[i+n] = place;
}
}
}
关于我的渐变生成器的旁注,我知道 Ken Perlin 使用 255,因为他使用的是位,我只是随机选择了它。我认为如果改变它对模式没有任何影响。
【问题讨论】:
-
"Perlin 用的是 255,因为他用的是比特,我只是随便挑的"...你应该先实现原始算法,然后修改它。
-
我有一个非常简单的算法版本,它不是最高效也不是最复杂的,但它仍然是原始算法。
-
“我认为如果改变它对模式没有任何影响” - 那么你在猜测。验证很容易,您应该这样做。此外,您可以选择将种子传递给构造函数以初始化 RNG。如果不这样做,您将永远无法重现特定的问题案例,也无法确定您是否真的修复了它们。
-
我检查并切换了 p[] 的长度,但没有任何改变。另外,这不是一个特定的问题案例,每次运行程序时都会出现这样的模式。
标签: java algorithm perlin-noise