用值噪声与 fbm 在 Canvas 上生成可复现的山体轮廓
【摘要】 静态风景页不需要 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)