思路:
1、引入 three-nebula插件
2、制作下雨、下雪。
这里雪用的是Sprite, 而雨的效果用的是THREE.Mesh, 因为Sprite的长宽不好设置
const createSnow = () => {
let map = new THREE.TextureLoader().load(snow);
let material = new THREE.SpriteMaterial({
map: map,
transparent: true,
side: THREE.DoubleSide,
color: 0xffffff,
blending: THREE.AdditiveBlending,
fog: true,
depthTest: false
});
return new THREE.Sprite(material);
};
const createEmitter = (camera, renderer) => {
const emitter = new Emitter();
const position = new Position();
position.addZone(new BoxZone(5000, 10, 5000));
return emitter
.setRate(new Rate(new Span(34, 48), new Span(0.2, 0.5)))
.addInitializers([
new Mass(1),
new Radius(new Span(20, 30)),
position,
new Life(5, 10),
new Body(createSnow()),
new RadialVelocity(0, new Vector3D(0, -1, 0), 90),
])
.addBehaviours([
new RandomDrift(10, 1, 10, 0.05),
new Rotate('random', 'random'),
new Gravity(10),
new CrossZone(new ScreenZone(camera, renderer, 20, '234'), 'dead'),
])
.setPosition({y: 1500})
.emit();
};
const createRain2 = () => {
let map = new THREE.TextureLoader().load(raindrop);
let material = new THREE.MeshLambertMaterial({
color: 0x00ffff,
map: map,
side: THREE.DoubleSide, //两面可见
transparent: true, //需要开启透明度计算,否则着色器透明度设置无效
// opacity: 0.5,//整体改变透明度
depthTest: false,
blending: THREE.AdditiveBlending,
});
return new THREE.Mesh( new THREE.PlaneGeometry( 0.3, 2 ),
material)
}
const createEmitter2 = (camera, renderer) => {
const emitter = new Emitter();
const position = new Position();
position.addZone(new BoxZone(10000, 10, 10000));
return emitter
.setRate(new Rate(new Span(300, 400), new Span(0.2, 0.3)))
.addInitializers([
new Mass(1),
new Radius(new Span(20, 30)),
position,
new Life(5, 10),
new Body(createRain2()),
new RadialVelocity(0, new Vector3D(0, -1, 0), 90),
])
.addBehaviours([
new RandomDrift(10, 1, 10, 0.05),
// new Rotate('random', 'random'),
new Gravity(13),
new CrossZone(new ScreenZone(camera, renderer, 20, '234'), 'dead'),
])
.setPosition({y: 2500})
.emit();
};
let nebulaRenderer = new SpriteRenderer(scene, THREE);
let nebulaSystem = new ParticleSystem();
snowEmitter = createEmitter(camera, renderer);
rainEmitter = createEmitter2(camera, renderer);
// 默认关闭粒子效果 由按钮控制开始
rainEmitter.isEmitting = false
snowEmitter.isEmitting = false
nebula = nebulaSystem
.addRenderer(nebulaRenderer)
nebula.addEmitter(rainEmitter)
nebula.addEmitter(snowEmitter);
function animal() {
if (nebula) {
nebula.update();
}
renderer.render(scene, camera)
requestAnimationFrame(animal)
}
3、关于场景效果的切换( 比如停止下雪,换成下雨)
设置totalEmitTimes currentEmitTime 属性即可。
if (!snowEmitter.isEmitting) {
snowEmitter.isEmitting = true
}
snowEmitter.totalEmitTimes = Infinity;
snowEmitter.currentEmitTime = 0;
rainEmitter.totalEmitTimes = -1;
rainEmitter.currentEmitTime = 0;