在实时图形和视觉效果中,波动能为场景增添令人惊叹的动态效果。本文将着重介绍如何在 Three.js 中实现一个波动效果的平面(WavePlane),该平面可以通过对 3D 模型应用简单的噪声函数来自然生成波动效果。
import * as THREE from 'three'
import { createNoise2D } from 'simplex-noise'
type PlaneConfigType = {
color: string | number
width: number
height: number
segments: number
}
export class WavePlane {
entity: any
simplex: any
factor: number
cycle: number
scale: number
speed: number
constructor(
planeConfig: PlaneConfigType = {
width: 5000,
height: 5000,
color: 0x7ee6e7,
segments: Math.pow(2, 8),
}
) {
const { width, height, segments, color } = planeConfig
const geometry = new THREE.PlaneGeometry(width, height, segments, segments)
const material = new THREE.MeshLambertMaterial({
color: '#202020',
emissive: color,
opacity: 0.1,
blending: THREE.NoBlending,
side: THREE.FrontSide,
transparent: false,
depthTest: false,
wireframe: true,
})
this.entity = new THREE.Mesh(geometry, material)
this.entity.rotation.set(Math.PI / 2, 0, 0)
this.simplex = createNoise2D()
this.factor = 300
this.cycle = 0
this.scale = 30
this.speed = 0.005
}
boostrap(threeCore: any) {
threeCore.scene.add(this.entity)
threeCore.mixins.set('WavePlane', () => this.update())
}
update() {
const positionAttribute = this.entity.geometry.attributes.position
positionAttribute.needsUpdate = true
for (let i = 0; i < positionAttribute.count; i++) {
const x = positionAttribute.getX(i)
const y = positionAttribute.getY(i)
const xoff = x / this.factor
const yoff = y / this.factor + this.cycle
let rand = this.simplex(xoff, yoff) * this.scale
positionAttribute.setZ(i, rand)
}
this.cycle += this.speed
}
}