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

如何为Perlin噪声生成伪随机梯度?网格点梯度重复方法咨询

关于Perlin噪声梯度生成与周期性实现的解答

一、Perlin噪声的伪随机梯度生成方法

Perlin噪声的梯度生成核心是固定梯度池+伪随机置换表的组合,具体步骤如下:

  • 第一步:预定义梯度向量池
    2D场景下常用单位圆内/附近的8个方向向量(也可扩展为16个更精细的归一化方向),示例:
    // 2D梯度池(可选择归一化到单位长度)
    const gradients = [
      [1, 1], [-1, 1], [1, -1], [-1, -1],
      [1, 0], [-1, 0], [0, 1], [0, -1]
    ];
    
    3D场景则对应单位球面上的12或24个方向向量。
  • 第二步:生成伪随机置换表
    创建长度为256的数组填充0-255整数,用Fisher-Yates洗牌打乱顺序,再重复一次得到512长度的表(简化边界运算)。示例代码:
    function generatePermutationTable(seed = 1) {
      const perm = Array.from({length: 256}, (_, i) => i);
      // Fisher-Yates洗牌保证随机性
      for (let i = 255; i > 0; i--) {
        const j = Math.floor((seed * Math.random()) * (i + 1));
        [perm[i], perm[j]] = [perm[j], perm[i]];
      }
      return perm.concat(perm);
    }
    
  • 第三步:格点到梯度的映射
    对任意整数格点(ix, iy),通过哈希运算映射到置换表索引,再从梯度池取对应向量。常用哈希逻辑:
    function getGradient(perm, ix, iy) {
      const idx = perm[(perm[ix & 255] + iy) & 255];
      return gradients[idx % gradients.length];
    }
    
    & 255等价于取模256,确保索引在有效范围内,同时保证相同格点始终返回同一梯度。

二、单位圆内梯度的周期性重复实现

梯度的周期性重复本质是让格点到梯度的映射关系循环,核心依赖置换表的循环特性:

  • 用置换表长度控制周期:
    若希望噪声周期为N个单位长度,将置换表基础长度设为N(推荐2的幂,如64、256),哈希时对格点坐标做ix & (N-1)(等价于取模N,性能更高)。当格点坐标超过N时,取模后的结果循环,哈希索引重复,梯度自然周期性出现。
  • 自定义周期示例(周期64):
    const PERIOD = 64;
    const perm = generatePermutationTable(1).slice(0, PERIOD).concat(generatePermutationTable(1).slice(0, PERIOD));
    
    function getPeriodicGradient(ix, iy) {
      const idx = perm[(perm[ix & (PERIOD-1)] + iy) & (PERIOD-1)];
      return gradients[idx % gradients.length];
    }
    
  • 注意事项:
    • 非2的幂周期可直接用ix % PERIOD代替位运算,仅性能略降;
    • 梯度池无需额外处理,只要映射关系循环,梯度就会同步重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:46:09