用值噪声与 fbm 在 Canvas 上生成可复现的山体轮廓

举报
yd_296587128 发表于 2026/11/06 10:31:34 2026/11/06
【摘要】 静态风景页不需要 3D 管线。值噪声加上分形叠加只有几十行,配合 2D Canvas 就能得到足够自然的山脊,而且没有构建步骤、没有依赖,双击 index.html 就能看。

这篇记录一个实际项目里的取舍与实现细节,重点放在「为什么这样做」而不是「调了哪个参数」,希望顺手能复用到类似场景。

为什么不直接上 WebGL

静态风景页不需要 3D 管线。值噪声加上分形叠加只有几十行,配合 2D Canvas 就能得到足够自然的山脊,而且没有构建步骤、没有依赖,双击 index.html 就能看。

格点哈希取代 Math.random

把连续坐标映射到整数格点,每个格点用一个整数位混合的哈希函数给值。用哈希而不是随机数,是为了让同一个种子在任何机器、任何时刻都画出同一张图;随机数一旦参与,可复现性就没了。

function fbm(x, y, seed, octaves = 5) {
  let amp = 1, freq = 1, sum = 0, norm = 0;
  for (let i = 0; i < octaves; i++) {
    sum += amp * noise(x * freq, y * freq, seed + i * 131);
    norm += amp;
    amp *= 0.5;
    freq *= 2.0;
  }
  return sum / norm;
}

分形叠加的最小实现。

fade 曲线决定手感

线性插值会在格点处留下折角,山脊看起来像折纸。换成 t*t*(3-2t) 或五次曲线后,轮廓立刻变软,这也是很多人手写噪声时第一个要修的细节。

分形叠加与大气透视

把 4 到 6 层 octave 按振幅减半、频率翻倍叠起来。远景振幅小、频率低,近景反之。每层用基色向天空色做一次线性混合,越远越接近天空色,雾感就自然出来了。

小结

程序化画面的门槛不在数学,而在约束。先把「零依赖、可复现、单文件」定死,实现方案基本是被逼出来的最优解。

如果这套思路与你的场景有共鸣,欢迎在评论区说说你踩过的坑。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。