我一直在试验perlin noie世代的游戏,我想编程,但我遇到了一些奇怪的结果。当我让我的代码运行,并绘制灰度我获得下面的图片结果:Perlin噪声发生器的奇怪结果
我基于Perlin杂维基百科页面和参考页面(下面的链接)的一个我的代码。基于半随机向量的预生成网格,可以生成每点Perlin噪声点。
public static double[][] generateMap(long seed, int width, int height) {
double[][] map = new double[width][height];
double[][][] grid = generateGrid(seed, (int) (width/10)+1, (int) (height/10)+1);
double max = Double.MIN_VALUE;
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
double p = perlinNoise(((double) i)/10, ((double) j)/10, grid);
map[i][j] = p;
max = (max < p) ? p : max;
}
}
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
map[i][j] = map[i][j]/max;
}
}
return map;
}
private static double perlinNoise(double x, double y, double[][][] grid) {
int x0 = ((x < 0) ? (int) x-1 : (int) x);
int y0 = ((y < 0) ? (int) y-1 : (int) y);
int x1 = x0 + 1;
int y1 = y0 + 1;
double tx = x - (double)x0;
double ty = y - (double)y0;
double wx = tx*tx*(3-2*tx);
double wy = ty*ty*(3-2*ty);
double l0, l1, ix, iy, p;
l0 = dotGrid(x0, y0, x, y, grid);
l1 = dotGrid(x1, y0, x, y, grid);
ix = cerp(l0, l1, wx);
l0 = dotGrid(x0, y1, x, y, grid);
l1 = dotGrid(x1, y1, x, y, grid);
iy = cerp(l0, l1, wx);
p = cerp(ix, iy, wy);
return p;
}
private static double lerp(double a, double b, double w) {
return (1.0f - w)*a + w*b;
}
private static double cerp(double a, double b, double w) {
double ft = w * 3.1415927;
double f = (1 - Math.cos(ft)) * 0.5;
return a*(1-f) + b*f;
}
private static double dotGrid(int i, int j, double x, double y, double[][][] grid) {
double dx = x - i;
double dy = y - j;
return (dx*grid[i][j][0] + dy*grid[i][j][1]);
}
private static double[][][] generateGrid(long seed, int width, int height) {
Random r = new Random(seed);
double[][][] grid = new double[width][height][2];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
double x = r.nextFloat();
double y = r.nextFloat();
double v = Math.sqrt((x*x) + (y*y));
grid[i][j][0] = x/v;
grid[i][j][1] = y/v;
}
}
return grid;
}
对于那些想测试我的代码也将包括我的渲染方法:
private void drawMap(double[][] map, Graphics g) {
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
float d = (float) Math.abs(map[i][j]);
d = (d > 1.0f) ? 1.0f : d;
Color c = new Color(d, d, d);
g.setColor(c);
g.fillRect(i, j, 1, 1);
}
}
}
我希望有人能告诉我为什么我在我的噪点来得到这些奇怪的迷宫一样的结构和如何摆脱它们。
来源:
http://en.wikipedia.org/wiki/Perlin_noise
http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html
感谢您的帮助,它显着改善了我的代码输出。然而,我还不完全满足。我可能应该在我的第一篇文章中说明了这一点,但我正在寻找一种更多像阴云一样蓬松的输出,而不是我现在得到的东西。我已经考虑过使用八度音的方法,这里解释:http://freespace.virgin.net/hugo.elias/models/m_perlin.htm,但不知何故,我觉得这种方法效率很低。 – Exevan 2014-10-28 15:58:23
是的,为了得到“云”,你必须一起添加多个柏林噪音八度。 – uesp 2014-10-28 16:25:07