【问题标题】:Perlin noise problem: clearly visible lines in resultPerlin 噪声问题:结果中的线条清晰可见
【发布时间】:2020-08-24 21:48:12
【问题描述】:

我一直在用 python 实现一个 perlin noice 生成器。 它工作得很好,除了结果中的线条清晰可见。

问题似乎与我在 X 方向的渐变之间切换的位置有关。

代码如下:

from random import randint, seed
from PIL import Image
from numpy import asarray, interp, uint8

seed(1)
gradients = []
for x in range(20):
    gradients.append([])
    for y in range(20):
        gradients[x].append([randint(-1,1), randint(-1,1)])

def getInfluenceValue(x,y,Xgrad,Ygrad):
    return ((gradients[Xgrad][Ygrad][0] * (x-Xgrad)) + (gradients[Xgrad][Ygrad][1]*(y-Ygrad)))
    
def lerp(v0,v1,t):
    return (1 - t) * v0 + t * v1;

def fade(t):
    return 3*pow(t,2) - 2*pow(t,3)

def perlin(x, y):
    X0 = int(x) 
    Y0 = int(y)
    X1 = X0+1
    Y1 = Y0+1
    sx = fade(float(x) - float(X0));
    sy = fade(float(y) - float(Y0));
    topLeftDot = getInfluenceValue(x,y,X0,Y1)
    topRightDot = getInfluenceValue(x,y,X1,Y1) 
    bottomLeftDot = getInfluenceValue(x,y,X0,Y0)
    bottomRightDot = getInfluenceValue(x,y,X1,Y0)

    return lerp(lerp(topLeftDot, topRightDot, sx), lerp(bottomLeftDot, bottomRightDot, sx), sy)

tmp_list = []
for x in range(1000):
    tmp_list.append([])    
    for y in range(1000):
        tmp_list[x].append(perlin(x/100.0, y/100.0))

data = asarray(tmp_list)
rescaled = interp(data, (data.min(), data.max()), (0, 255)).astype(uint8)
Image.fromarray(rescaled).save('test.png')

结果如下:

我已经尝试替换 lerp 功能,并且我使用了其他淡入淡出功能。但问题依然存在。这是怎么回事?

PS。我在 stackoverflow 上看到了其他关于“块状”导致 perlin 噪声生成的问题,但由于这个结果似乎只是在 1 个方向/维度上是“块状”的,我认为这个问题与这些问题无关。

【问题讨论】:

  • 您基本上是在寻求帮助调试您的代码的人。如果您至少添加一个关于您的代码做什么(或试图做什么)的概述,那将会很有帮助。

标签: python numpy perlin-noise


【解决方案1】:

为了回答您的问题,我不确定这是否是整个问题,但我确实看到了一个错误。在 X 中,你沿着 sx 从 X0 到 X1。但是在 Y 中,你沿着 sy 从 Y1 到 Y0。在 topLeftDot-bottomRightDot 变量中交换 Y1/Y0 应该可以解决这个问题。或者,切换哪些变量位于 lerp 返回行的哪些部分。如果这不能解决问题,请尝试反转 X0/X1。我想知道为什么您的图像显示不连续性打破了 X 轴而不是打破了 Y 轴。

补充一点,我看到您正在使用整数转换将 x,y 转换为 X0 和 Y0。这适用于正数,但可能不适用于负数。请参阅this question and its answers 了解更多信息。

最后,我的一般建议:Perlin 是一种旧的噪声处理方法,往往会产生非常网格对齐的结果。一旦你让你的噪音工作,或者如果你看一下 Perlin 噪音的其他图像,a lot of the parts of the noise are aligned 45 or 90 degrees 可能会变得很明显(Perlin 是第一行)。这可能是一项有益的编程练习,但如果您比编程练习更深入,那么我建议您编写代码或使用良好的 Simplex 或 Simplex-related 噪声实现。请参阅 this post 了解有关从 Perlin 实现 2D 单纯形噪声的详细信息,或 this 如果您希望在项目中使用易于导入的单纯形相关噪声。

【讨论】:

  • 谢谢,正如你所说的切换 Y 变量解决了这个问题,似乎我把左下角视为(0,0)而犯了一个错误。是的,这只是用作编程练习。我已经实现了用于地形生成的 perlin 噪声和菱形平方算法。并且正在考虑接下来实施单纯形噪声。因此,感谢您提供指向 simplex noice 的链接。
【解决方案2】:

看起来唯一的问题是底部顶部在 Y 插值中反转。 这会导致 vertical 条带,因为根据代码的设置方式,Y 是 horizo​​ntal 轴。

将 return 语句切换为“bottom”第一个“top”第二个:

return lerp(lerp(bottomLeftDot, bottomRightDot, sx), lerp(topLeftDot, topRightDot, sx), sy)

产生以下 Perlin 噪声图像:

【讨论】:

    猜你喜欢
    • 2013-10-11
    • 2014-10-06
    • 2020-06-06
    • 1970-01-01
    • 2014-02-15
    • 2021-09-04
    • 2011-07-28
    • 2011-09-20
    • 2021-06-30
    相关资源
    最近更新 更多