创建云朵类
class Clouds{
constructor(
// 云朵高度
height = 5,
// 粒子大小
size = 20,
// 云朵方块大小
scale = 5,
autoRotate = true
){
this.height = height
this.num = num
this.size = size
this.scale = scale
this.autoRotate = autoRotate
// 纹理加载器
const textureLoader = new THREE.TextureLoader()
// 加载三个纹理
const map1 = textureLoader.load('path')
const map2 = textureLoader.load('path')
const map3 = textureLoader.load('path')
// 声明材质数组
const materials = []
// 创建粒子材质 1 2
const material1 = new THREE.PointsMaterial({
size: this.size * 0.2,
transparent : true,
blending: THREE.AdditiveBlending,
color : 0xffffff,
// 深度检测
depthWrite : false,
depthTest : false,
map: map1,
alphaMap : map2, // 透明贴图
})
// 2 3
const material2 = new THREE.PointsMaterial({
size: this.size * 0.4,
transparent : true,
blending: THREE.AdditiveBlending,
color : 0xffffff,
// 深度检测
depthWrite : false,
depthTest : false,
map : map2,
alphaMap : map3
})
// 3 1
const material3 = new THREE.PointsMaterial({
size: this.size * 0.6,
transparent : true,
blending: THREE.AdditiveBlending,
color : 0xffffff,
// 深度检测
depthWrite : false,
depthTest : false,
map : map3,
alphaMap : map2
})
// 2 1
const material4 = new THREE.PointsMaterial({
size: this.size * 0.8,
transparent : true,
blending: THREE.AdditiveBlending,
color : 0xffffff,
// 深度检测
depthWrite : false,
depthTest : false,
map : map2,
alphaMap : map1
})
materials.push(material1, material2, material3, material4)
this.mesh = new THREE.Group()
// 每种材质生成一种粒子效果
for(let i = 0; i < materials.length;i++){
let material = materials[i]
const geometry = this.createGeometry()
const points = new THREE.Points(geometry,material)
this.mesh.add(points)
}
if(this.autoRotate){
this.animate()
}
}
// 创建几何体
createGeometry(num = 100){
// 声明顶点数组
const positionArr = []
const geometry = new THREE.BufferGeometry()
for(let i = 0;i < num;i++){
let randomX = (Math.random() - 0.5) * 2 * this.scale
let randomY = Math.random() * (this.height / 2) + this.height
let randomZ = (Math.random() - 0.5) * 2 * this.scale
positionArr.push(randomX, randomY, randomZ)
}
// 给几何体设置属性
geometry.setAttribute('position',
new THREE.Float32BufferAttribute(positionArr,3))
return geometry
}
// 运动函数
animate(){
// 声明一个变量,用来计算速度
let i = 1
// 遍历Group
this.mesh.traverse(item =>{
let speed = 20 * i
// 根据类型
if(item instanceof THREE.Points){
gsap.to(item.rotation,{
duration : speed,
repeat: -1,
y : Math.PI *2
})
}
i++
})
}
}
创建海洋类
class Ocean {
constructor(radius = 1000) {
// 创建水平
this.waterGeometry = new THREE.CircleBufferGeometry(radius, 128);
this.water = new Water(this.waterGeometry, {
textureWidth: 1024,
textureHeight: 1024,
color: 0x08dbea,
flowDirection: new THREE.Vector2(1, 1), // 流动方向二维向量
scale: 100,
});
this.water.position.y = -5;
this.water.rotation.x = -Math.PI / 2;
this.mesh = this.water;
// 渲染优先级
this.water.renderOrder = -1;
// 根据视图动态修改海面的效果
this.water.material.fragmentShader =
this.water.material.fragmentShader.replace(
"gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );",
`
gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );
// 根据z轴,动态算出gl_FragColor与vec4的混合比例
gl_FragColor = mix( gl_FragColor, vec4(0.05,0.3,0.7,1.0), vToEye.z*0.0005+0.5 );
`
);
}
需要将three自带的水纹理手动放到项目的资源根目录下的"textures\water"