Threejs 下雨下雪粒子效果

在这里插入图片描述
在这里插入图片描述
思路:
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;
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值