You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于相邻值一、二阶导数相对较小的随机数生成器的技术问询

嘿,你说的这种能生成平滑波浪状随机数的生成器,其实就是咱们图形/游戏开发里常用的**梯度噪声(Gradient Noise)**家族!最经典的就是Perlin Noise,后来还有改进的Simplex Noise,它们的核心就是保证相邻数值的一阶、二阶导数连续,所以画出来的曲线是平滑的波浪,完美适配地形生成、纹理制作这类场景。下面我给你拆解下实现方法和关键技术细节:

核心原理:为什么能生成平滑波形?

普通随机数是离散跳变的——比如你随机取一串数,相邻值可能突然从0跳到1,完全没有过渡。而梯度噪声的思路是:

在规则网格的每个顶点上定义一个随机的梯度向量,然后对网格内的任意点,通过平滑插值计算它与周围顶点梯度向量的关联值,最终输出的数值自然是连续且平滑过渡的,一阶、二阶导数也能保持稳定。

经典实现:Perlin Noise

Perlin Noise是最基础也最常用的平滑噪声,我们以2D版本为例,拆解实现步骤:

1. 初始化置换表与梯度向量

首先要创建一个置换表(permutation table),用来避免重复的梯度模式,同时解决边界循环问题:

import random
import math

# 生成0-255的随机置换表,复制一份避免索引越界
permutation = list(range(256))
random.shuffle(permutation)
permutation *= 2

梯度向量的选择不用提前存储,我们可以通过哈希值动态生成(比如用hash值映射到4种2D梯度向量),这样更省内存。

2. 平滑步进函数(关键!保证平滑的核心)

不能用普通的线性插值,必须用一个在t=0和t=1处一阶、二阶导数都为0的平滑函数,Perlin本人用的是:

def fade(t):
    # 6t⁵ -15t⁴ +10t³,保证插值点的导数连续
    return t * t * t * (t * (t * 6 - 15) + 10)

这个函数能让插值过程完全平滑,不会出现生硬的拐点。

3. 点积计算与双线性插值

对于任意输入点(x,y),我们找到它所在的网格单元,计算它到四个顶点的偏移量,再结合梯度向量做点积,最后用平滑步进值插值:

def grad(hash_val, x, y):
    # 根据哈希值映射到4种2D梯度向量
    h = hash_val & 3
    if h == 0:
        return x + y
    elif h == 1:
        return -x + y
    elif h == 2:
        return x - y
    else:
        return -x - y

def perlin_noise(x, y):
    # 找到当前点所在网格的左上角顶点索引
    xi = int(x) & 255
    yi = int(y) & 255
    # 计算点到顶点的偏移量
    xf = x - int(x)
    yf = y - int(y)
    # 获取平滑步进值
    u = fade(xf)
    v = fade(yf)
    # 计算四个顶点的哈希值
    aa = permutation[permutation[xi] + yi]
    ab = permutation[permutation[xi] + yi + 1]
    ba = permutation[permutation[xi + 1] + yi]
    bb = permutation[permutation[xi + 1] + yi + 1]
    # 计算每个顶点的梯度点积
    x1 = grad(aa, xf, yf)
    x2 = grad(ba, xf - 1, yf)
    y1 = grad(ab, xf, yf - 1)
    y2 = grad(bb, xf - 1, yf - 1)
    # 双线性插值得到最终噪声值
    return (x1 + u * (x2 - x1)) + v * ((y1 + u * (y2 - y1)) - (x1 + u * (x2 - x1)))
改进版:Simplex Noise

Perlin Noise在高维场景下(比如3D、4D)计算效率低,而且存在轻微的方向性瑕疵。Simplex Noise解决了这些问题:

  • 用三角形/四面体网格替代正方形/立方体网格,高维下需要计算的顶点数更少(2D从4个减到3个)
  • 梯度向量的分布更均匀,减少了方向性偏差
  • 计算速度比同维度的Perlin Noise快30%左右

它的核心逻辑和Perlin类似,只是网格结构和插值方式做了优化,如果你需要高维噪声或者更高的性能,优先选Simplex Noise。

进阶技巧:让噪声更实用

单纯的基础噪声不够逼真,通常会结合这些技巧来适配场景:

  • 八度叠加(Octave Noise):把不同频率、振幅的噪声叠加,高频加细节,低频定轮廓,生成更真实的地形:
    def octave_perlin(x, y, octaves=4, persistence=0.5):
        total = 0
        frequency = 1
        amplitude = 1
        max_value = 0
        for _ in range(octaves):
            total += perlin_noise(x * frequency, y * frequency) * amplitude
            max_value += amplitude
            amplitude *= persistence
            frequency *= 2
        return total / max_value  # 归一化到[-1,1]
    
  • 湍流(Turbulence):取噪声的绝对值后叠加,生成类似岩石、粗糙表面的纹理
  • 域扭曲(Domain Warping):用噪声值扭曲输入坐标,生成流动感更强的效果(比如云层、水流)
其他变种:Worley Noise(细胞噪声)

如果需要类似细胞、生物纹理的平滑效果,Worley Noise是另一个选择——它计算点到随机特征点的距离,再通过插值生成平滑的细胞状图案,适合模拟皮肤、岩石、木纹这类纹理。

内容的提问来源于stack exchange,提问作者Maurdekye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:11:40