我的问题是我的perlin噪音在非常小的空间中非常明显地重复。 Here is an image of what it going on.我知道这确实发生在所有perlin噪音的某个点之后,但它似乎几乎立即发生在我的身上。我相信它是由我非常糟糕的伪随机梯度生成器引起的,但我不确定。我的代码如下。
作为旁注,我的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,因为他正在使用位,我只是随机选择它。如果它被改变,我认为它对模式没有任何影响。
答案 0 :(得分:0)
您的直觉是正确的。您计算:
int units = unitX+unitY;
,然后将其用作所有渐变表查找的基础。这样可以保证您在坡度为-1的线上获得相同的值,这正是我们假设(0,0)是左上角的情况。
我建议使用一个真正的哈希函数来组合您的坐标:xxHash,Murmur3甚至是像CRC32这样的东西(这并不意味着是哈希)会比您正在做的事情要好得多。您还可以实现Perlin的原始哈希函数,尽管它具有各向异性的已知问题。