二维柏林噪声看起来很奇怪
2D Perlin Noise looking odd
我不确定我的 Perlin 噪声发生器是否正常工作,它产生的噪声看起来与我在网上看到的图像非常不同。我的看起来太单一了(这是三张不同的图片):
而我通常看到的是这样的:
我的代码基本上是:
/* Get the coord of the top-left gradient of the grid (y, x) falls in */
int j = floor(x);
int i = floor(y);
/* Get the distance (y, x) is from it */
double dx = x-j;
double dy = y-i;
/* Influence of (g)radient(i)(j) (starting at the top-left one) */
double g00 = dot(grad(hashes, hsize, grads, i, j), dy, dx);
double g01 = dot(grad(hashes, hsize, grads, i, j+1), dy, dx-1);
double g10 = dot(grad(hashes, hsize, grads, i+1, j), dy-1, dx);
double g11 = dot(grad(hashes, hsize, grads, i+1, j+1), dy-1, dx-1);
/* Interpolate the influences using the blending function */
/* Linear interpol the top 2 */
double lt = lerp(g00, g01, fade(dx));
/* Linear interpol the bottom 2 */
double lb = lerp(g10, g11, fade(dx));
/* Linear interpol lb lt, completing the bilienear interpol */
return lerp(lt, lb, fade(dy));
Complete code. It's based mainly on this tutorial. I'm using this script 绘制 csv 文件。
我了解基础知识,但在阅读了几个通常相互矛盾的 "tutorials" 和可读性不佳的 "reference implementation" 之后,我有一些疑问。内插的(x, y)
点应该在什么区间内?据我了解,它应该是 [0, GRID_SIZE-1]
(例如 [0, 255]
如果使用预先计算的 table 和 256 个随机值)。但是,当 (x, y)
映射到 [0, 1]
时,我的代码只会产生相当好看的图像,而且我在网上看到一些实现将它映射到 [0, 255]
,无论网格大小如何。我也不确定我是否从 table.
中正确选择了渐变
您将像素坐标标准化为整个图像。您应该将其标准化为单纯形网格的大小。
因此,代替您的内循环代码:
double x = j/(double)w;
double y = i/(double)h;
做:
double x = j / gridsize;
double y = i / gridsize;
其中网格大小是附加参数,例如:
double gridsize = 32.0;
(可能应该选择它以均匀地适合图像尺寸。)
我不确定我的 Perlin 噪声发生器是否正常工作,它产生的噪声看起来与我在网上看到的图像非常不同。我的看起来太单一了(这是三张不同的图片):
而我通常看到的是这样的:
我的代码基本上是:
/* Get the coord of the top-left gradient of the grid (y, x) falls in */
int j = floor(x);
int i = floor(y);
/* Get the distance (y, x) is from it */
double dx = x-j;
double dy = y-i;
/* Influence of (g)radient(i)(j) (starting at the top-left one) */
double g00 = dot(grad(hashes, hsize, grads, i, j), dy, dx);
double g01 = dot(grad(hashes, hsize, grads, i, j+1), dy, dx-1);
double g10 = dot(grad(hashes, hsize, grads, i+1, j), dy-1, dx);
double g11 = dot(grad(hashes, hsize, grads, i+1, j+1), dy-1, dx-1);
/* Interpolate the influences using the blending function */
/* Linear interpol the top 2 */
double lt = lerp(g00, g01, fade(dx));
/* Linear interpol the bottom 2 */
double lb = lerp(g10, g11, fade(dx));
/* Linear interpol lb lt, completing the bilienear interpol */
return lerp(lt, lb, fade(dy));
Complete code. It's based mainly on this tutorial. I'm using this script 绘制 csv 文件。
我了解基础知识,但在阅读了几个通常相互矛盾的 "tutorials" 和可读性不佳的 "reference implementation" 之后,我有一些疑问。内插的(x, y)
点应该在什么区间内?据我了解,它应该是 [0, GRID_SIZE-1]
(例如 [0, 255]
如果使用预先计算的 table 和 256 个随机值)。但是,当 (x, y)
映射到 [0, 1]
时,我的代码只会产生相当好看的图像,而且我在网上看到一些实现将它映射到 [0, 255]
,无论网格大小如何。我也不确定我是否从 table.
您将像素坐标标准化为整个图像。您应该将其标准化为单纯形网格的大小。
因此,代替您的内循环代码:
double x = j/(double)w;
double y = i/(double)h;
做:
double x = j / gridsize;
double y = i / gridsize;
其中网格大小是附加参数,例如:
double gridsize = 32.0;
(可能应该选择它以均匀地适合图像尺寸。)