包裹 2D 柏林噪声

发布于 2024-10-31 08:50:43 字数 212 浏览 0 评论 0原文

我正在与 Perlin Noise 合作开发高度图生成算法,我想让它环绕边缘,以便它可以被视为连续的..有没有简单的方法或技巧可以做到这一点?我想我需要类似球形噪声的东西,以便它在水平和垂直方向上环绕。我也很高兴只有 1 个缠绕轴,但有两个会更好。

现在,我使用经典算法,您可以在其中设置要添加多少个八度音阶,以及用于更改每个连续八度音阶之间的波的幅度和频率的乘数。

提前致谢!

I'm working with Perlin Noise for a height map generation algorithm, I would like to make it wrap around edges so that it can been seen as continuous.. is there a simple way or trick to do that? I guess I need something like a spherical noise so that either horizontally and vertically it wraps around. I would be happy also with just 1 wrapping axis but two would be better.

For now I'm using the classical algorithm in which you can set up how many octaves you want to add and which are the multipliers used for changing amplitude and frequency of the waves between every successive octave.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光沙漏 2024-11-07 08:50:43

Perlin 噪声作为波形的总和获得。波形是通过插值随机值获得的,较高倍频程的波形具有较小的缩放因子,而插值的随机值彼此更接近。要进行环绕,您只需要以通常的环形方式在 y 轴和 x 轴周围正确插值,即,如果您的 X 轴从 x_min 跨越到 x_max,并且最左边的随机点(正在插值)是在 x0 处和最右边的 x1 处(x_min < x0 < x1 < x_max),通过从 x1 到 x0 插值(环绕边缘)获得 x1 右侧和 x0 左侧的插值像素的值。

这里是使用线性插值的八度之一的伪代码。假设一个 256 x 256 矩阵,其中 Perlin 噪声网格大小是两个像素的幂……只是为了使其可读。想象一下,例如大小==16:

 wrappable_perlin_octave(grid, size):
   for (x=0;x<256;x+=size):
     for (y=0;y<256;y+=size):
       grid[x][y] = random()
   for (x=0;x<256;x+=size):
     for (y=0;y<256;y+=size):
       if (x % size != 0 || y % size != 0): # interpolate
         ax = x - x % size
         bx = (ax + size) % 256 # wrap-around
         ay = y - y % size
         by = (ay + size) % 256 # wrap-around
         h = (x % size) / size # horizontal balance, floating-point calculation
         v = (y % size) / size # vertical balance, floating-point calculation
         grid[x][y] = grid[ax][ay] * (1-h) * (1-v) +
                      grid[bx][ay] * h * (1-v) +
                      grid[ax][by] * (1-h) * v +
                      grid[bx][by] * h * v

Perlin noise is obtained as the sum of waveforms. The waveforms are obtained by interpolating random values, and the higher octave waveforms have smaller scaling factors whereas the interpolated random values are nearer to each other. To make this wrap around, you just need to properly interpolate around the y- and x-axes in the usual toroidal fashion, i.e. if your X-axis spans from x_min to x_max, and the leftmost random point (which is being interpolated) is at x0 and the rightmost at x1 (x_min < x0 < x1 < x_max), the value for the interpolated pixels right to x1 and left from x0 are obtained by interpolating from x1 to x0 (wrapping around the edges).

Here pseudocode for one of the octaves using linear interpolation. This assumes a 256 x 256 matrix where the Perlin noise grid size is a power of two pixels... just to make it readable. Imagine e.g. size==16:

 wrappable_perlin_octave(grid, size):
   for (x=0;x<256;x+=size):
     for (y=0;y<256;y+=size):
       grid[x][y] = random()
   for (x=0;x<256;x+=size):
     for (y=0;y<256;y+=size):
       if (x % size != 0 || y % size != 0): # interpolate
         ax = x - x % size
         bx = (ax + size) % 256 # wrap-around
         ay = y - y % size
         by = (ay + size) % 256 # wrap-around
         h = (x % size) / size # horizontal balance, floating-point calculation
         v = (y % size) / size # vertical balance, floating-point calculation
         grid[x][y] = grid[ax][ay] * (1-h) * (1-v) +
                      grid[bx][ay] * h * (1-v) +
                      grid[ax][by] * (1-h) * v +
                      grid[bx][by] * h * v
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文