关于three.js:炫酷用Perlin-Noise生成随机地形

66次阅读

共计 1556 个字符,预计需要花费 4 分钟才能阅读完成。

良久不发 THREE.js 的教程了,明天给大家带了一个小案例,介绍如何用柏林噪声在 THREE.js 中生成随机地形,先来看下成果。

随机数和噪声


噪声实际上就是随机数生成器,一般噪声生成的随机数毫无法则可言。

在上世纪 80 年代,柏林噪声的发明者 Ken Perlin 尝试用一般噪声模仿随机成果,用于正在制作的经典迪士尼电影电子世界争霸战 (TRON),但始终无奈失去称心的成果,柏林噪声算法就这样应运而生。

2010 年 TRON 重拍版本

柏林噪声

自然界中层叠的山峦,大理石的纹理,海面高下起伏的波浪,这些景象看似横七竖八,却都有外在法则可循,一般的噪声无奈模拟出这些天然成果,柏林噪声算法使这些成为可能。

用柏林噪声算法能够失去一组平滑插值的随机数,它们之间互相关联,能够用来生成靠近天然的随机值。下图中,右边是一般噪声生成的随机纹理,左边是柏林噪声生成的纹理,能够看到后者生成的纹理更加天然平滑,随机值之间有显著过渡成果。

我用 canvas 绘制了两组图像,别离是用两种算法生成一些随机点,而后将这些点连接起来,能够看到右侧柏林噪声失去的是一条绝对平滑的曲线,而右边一般噪声的图形毫无法则可言。

一般噪声和柏林噪声随机点连线

生成随机地形

在 THREE.js 咱们用一个立体来生成随机地形,立体是由一系列顶点形成的,咱们只须要扭转这些顶点的 z 轴坐标值,就能产生高下起伏的成果,咱们先用随机噪声来试试。

let pos = this.groundGeo.attributes.position.array
for(let i = 0; i < pos.length; i+=3) {pos[i+2] = Math.random() * 2}
this.groundGeo.attributes.position.needsUpdate = true

随机噪声产生的地形

能够看到随机噪声产生的地形太过于僵硬,必定不是咱们想要的后果,再来试试柏林噪声。

let pos = this.groundGeo.attributes.position.array
for(let i = 0; i < pos.length; i+=3) {pos[i+2] = this.simplex.noise2D(tx, ty) * 2
}
this.groundGeo.attributes.position.needsUpdate = true

咱们失去了更加天然平滑的地形成果,这里咱们应用的 Simplex Noise 是柏林噪声的更高效,简介的实现,也是柏林噪声的作者提出的,这里咱们不关怀这些算法的实现细节。

柏林噪声产生的地形成果

挪动地形

要实现地形向观察者挪动,咱们只须要扭转柏林噪声的 x 坐标,让它随着工夫递增。

let pos = this.groundGeo.attributes.position.array
this.offsetX += 0.01
for(let i = 0; i < pos.length; i+=3) {
  let tx = this.offsetX
  let ty = this.offsetY
  tx += row * 0.05
  ty += col * 0.05
  pos[i+2] = this.simplex.noise2D(tx, ty) * 5
}
this.groundGeo.attributes.position.needsUpdate = true

这里应用一个 offsetX 变量,它的值在每帧循环中递增。留神,我只贴了要害代码,具体细节能够点击浏览原文来取得本案例的源文件。

通过调整各项参数,咱们还能够模拟出更多成果,例如:棱角分明的山峰,高下起伏的海浪,或者形状更加平滑的沙丘等等。

总结

Perlin Noise 柏林噪声在游戏和图形畛域被宽泛的利用,利用它能够模拟出许多乏味的视觉效果,你学到了嘛!

原文地址:https://dev.xingway.com/threejs-perline-noise/

正文完
 0