1,介绍

该示例使用的是 r95版本Three.js库。使用Threejs粒子效果实现下雨,下雪,阴天,晴天,火焰。
效果图如下:

2,主要说明

阴天,晴天实现方式,主要是替换场景的背景图片实现。

下雨、下雪、火焰主要用粒子实现,创建粒子有两种方式:

1,使用THREE.Points创建一个粒子集合,使用THREE.PointsMaterial来样式化粒子。

2,使用Three.Sprite()构造函数手工创建粒子。我们传入的唯一参数是材质,它只能是THREE.SpriteMaterial或THREE.SpriteCanvasMaterial。

Sprite适用创建少量的粒子,如果想创建大量粒子应该使用Points。

我这里使用Points实现下雨和下雪,主要代码如下:

function createPointRainy() {var img = rainy_sw == 1 ? "raindrop-4.png" : rainy_sw == 2 ? "snowflake3.png" : "";var name = rainy_sw == 1 ? "particles_rainy" : rainy_sw == 2 ? "particles_snowy" : "";var texture = new THREE.TextureLoader().load("assets/textures/particles/" + img);var geom = new THREE.Geometry();var material = new THREE.PointsMaterial({size: 1.5,transparent: true, // 是否设置透明度opacity: 1, // 透明map: texture, // 粒子材质blending: THREE.AdditiveBlending,sizeAttenuation: true, // 是否相同尺寸color: 0xffffff});var range = 120;for (var i = 0; i < 1500; i++) {var particle = new THREE.Vector3(Math.random() * range - range / 2,Math.random() * range * 1.5,1 + (i / 10 - 80))if (rainy_sw == 2) {// 定义雨滴以多快的速度落下,纵向运动速度的范围是0.1~0.3particle.velocityY = (0.1 + Math.random() / 5) - 0.1;// 定义粒子(雨滴)如何水平移动,横向运动速度的范围是-0.16~+0.16particle.velocityX = ((Math.random() - 0.5) / 3) - 0.05;} else {particle.velocityY = 0.15 + Math.random() / 5;particle.velocityX = (Math.random() - 0.5) / 3;}geom.vertices.push(particle);}cloud = new THREE.Points(geom, material);cloud.sortParticles = true;cloud.name = name;scene.add(cloud);
}

使用Sprite实现火焰效果,主要代码如下:

function initFlame() {var texture = new THREE.TextureLoader().load("assets/textures/particles/flamex.png");//sprite材质var material = new THREE.SpriteMaterial({//以canvas作为纹理map: texture,//混合度 加法混合blending: THREE.AdditiveBlending});//循环1000  添加粒子for (var i = 0; i < 2000; i++) {var particle = new THREE.Sprite(material);initParticle(particle, i);krq.add(particle);krq.name = "particles_flame";}scene.add(krq);
}

3,源码

<!DOCTYPE html>
<html><head><title>Threejs实现下雨,下雪,阴天,晴天,火焰</title><script type="text/javascript" src="libs/three.js"></script><script type="text/javascript" src="libs/OrbitControls.js"></script><script type="text/javascript" src="libs/OBJLoader.js"></script><script type="text/javascript" src="libs/other/Tween.min.js"></script><script type="text/javascript" src="libs/dat.gui.js"></script><style>body {margin: 0;overflow: hidden;}</style></head><body><div id="dom"></div><script type="text/javascript">var camera;var renderer;var cloud;var rainy_sw = 3; // 1雨2雪3晴4阴var flame_sw = true;//初始化一个空容器,装载粒子var krq = new THREE.Object3D();var textureLoader = new THREE.TextureLoader();function init() {// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。var scene = new THREE.Scene();var urls = ['assets/textures/cubemap/flowers/posx.jpg','assets/textures/cubemap/flowers/negx.jpg','assets/textures/cubemap/flowers/posy.jpg','assets/textures/cubemap/flowers/negy.jpg','assets/textures/cubemap/flowers/posz.jpg','assets/textures/cubemap/flowers/negz.jpg'];var urls1 = ['assets/textures/cubemap/flowers/posx1.jpg','assets/textures/cubemap/flowers/negx1.jpg','assets/textures/cubemap/flowers/posy1.jpg','assets/textures/cubemap/flowers/negy1.jpg','assets/textures/cubemap/flowers/posz1.jpg','assets/textures/cubemap/flowers/negz1.jpg'];var cubeLoader = new THREE.CubeTextureLoader();scene.background = cubeLoader.load(urls);// 创建一个摄像机,它定义了我们正在看的地方camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);// 将摄像机对准场景的中心camera.position.x = 10;camera.position.y = 50;camera.position.z = 90;camera.lookAt(scene.position);var orbit = new THREE.OrbitControls(camera);// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景renderer = new THREE.WebGLRenderer({antialias: true,logarithmicDepthBuffer: true,});renderer.setClearColor(new THREE.Color(0x121A39));renderer.setSize(window.innerWidth, window.innerHeight);var alight = new THREE.AmbientLight("#ffffff", 1);alight.name = "aLight";scene.add(alight);// 在屏幕上显示坐标轴var axes = new THREE.AxesHelper(100);// scene.add(axes);// 将平面添加到场景中createPlaneGeometryBasicMaterial();// 将呈现器的输出添加到HTML元素document.getElementById("dom").appendChild(renderer.domElement);// 使用GUI调试库var controls = new function() {this.rainy = function() {scene.remove(scene.getObjectByName("particles_snowy"));if (rainy_sw != 1) {rainy_sw = 1;scene.background = cubeLoader.load(urls1);scene.getObjectByName("aLight").intensity = 0.6;createPointRainy();}}this.snowy = function() {scene.remove(scene.getObjectByName("particles_rainy"));if (rainy_sw != 2) {rainy_sw = 2;scene.background = cubeLoader.load(urls1);scene.getObjectByName("aLight").intensity = 2;createPointRainy();}}this.sunny = function() {if (rainy_sw != 3) {scene.remove(scene.getObjectByName("particles_rainy"));scene.remove(scene.getObjectByName("particles_snowy"));scene.background = cubeLoader.load(urls);scene.getObjectByName("aLight").intensity = 1.2;rainy_sw = 3;}}this.cloudy = function() {if (rainy_sw != 4) {scene.remove(scene.getObjectByName("particles_rainy"));scene.remove(scene.getObjectByName("particles_snowy"));scene.background = cubeLoader.load(urls1);scene.getObjectByName("aLight").intensity = 1;rainy_sw = 4;}}this.flame = function() {if (flame_sw) {initFlame();flame_sw = !flame_sw;}}}var gui = new dat.GUI();gui.add(controls, 'rainy'); // 雨gui.add(controls, 'snowy'); // 雪gui.add(controls, 'sunny'); // 晴gui.add(controls, 'cloudy'); // 阴gui.add(controls, 'flame'); // 火焰// 启动动画renderScene();function createPointRainy() {var img = rainy_sw == 1 ? "raindrop-4.png" : rainy_sw == 2 ? "snowflake3.png" : "";var name = rainy_sw == 1 ? "particles_rainy" : rainy_sw == 2 ? "particles_snowy" : "";var texture = new THREE.TextureLoader().load("assets/textures/particles/" + img);var geom = new THREE.Geometry();var material = new THREE.PointsMaterial({size: 1.5,transparent: true, // 是否设置透明度opacity: 1, // 透明map: texture, // 粒子材质blending: THREE.AdditiveBlending,sizeAttenuation: true, // 是否相同尺寸color: 0xffffff});var range = 120;for (var i = 0; i < 1500; i++) {var particle = new THREE.Vector3(Math.random() * range - range / 2,Math.random() * range * 1.5,1 + (i / 10 - 80))if (rainy_sw == 2) {// 定义雨滴以多快的速度落下,纵向运动速度的范围是0.1~0.3particle.velocityY = (0.1 + Math.random() / 5) - 0.1;// 定义粒子(雨滴)如何水平移动,横向运动速度的范围是-0.16~+0.16particle.velocityX = ((Math.random() - 0.5) / 3) - 0.05;} else {particle.velocityY = 0.15 + Math.random() / 5;particle.velocityX = (Math.random() - 0.5) / 3;}geom.vertices.push(particle);}cloud = new THREE.Points(geom, material);cloud.sortParticles = true;cloud.name = name;scene.add(cloud);}function initFlame() {var texture = new THREE.TextureLoader().load("assets/textures/particles/flamex.png");//sprite材质var material = new THREE.SpriteMaterial({//以canvas作为纹理map: texture,//混合度 加法混合blending: THREE.AdditiveBlending});//循环1000  添加粒子for (var i = 0; i < 2000; i++) {var particle = new THREE.Sprite(material);initParticle(particle, i);krq.add(particle);krq.name = "particles_flame";}scene.add(krq);}/*** 粒子 延迟发散* @param particle* @param delay*/function initParticle(particle, delay) {particle.position.set(5, Math.random() + 5, 0);particle.scale.x = particle.scale.y = Math.random() * 3;//下面是一系列的动画var xx = Math.random() * 10 - 5;var yy = Math.cos((Math.PI / 100) * xx) * 20;//位移new TWEEN.Tween(particle.position).delay(delay).to({x: xx,y: yy,z: Math.random() * 10 - 5}, 2000).onComplete(function() {initParticle(particle, delay);}).start();// 大小new TWEEN.Tween(particle.scale).delay(delay).to({x: 0.01,y: 0.01}, 1000).start();}/*** 创建地面并添加材质* wrapS属性定义的是纹理沿x轴方向的行为,而warpT属性定义的是纹理沿y轴方向的行为。* Three.js为这些属性提供了如下两个选项:* ·THREE.RepeatWrapping允许纹理重复自己。* ·THREE.ClampToEdgeWrapping是属性的默认值。* 属性值为THREE.ClampToEdgeWrapping时,那么纹理的整体不会重复,只会重复纹理边缘的像素来填满剩下的空间。*/function createPlaneGeometryBasicMaterial() {var cubeMaterial = new THREE.MeshStandardMaterial({map: textureLoader.load("assets/textures/stone/cd.jpg"),side: THREE.DoubleSide,});cubeMaterial.map.wrapS = THREE.RepeatWrapping;cubeMaterial.map.wrapT = THREE.RepeatWrapping;cubeMaterial.map.repeat.set(3, 3)// 创建地平面并设置大小var planeGeometry = new THREE.PlaneGeometry(100, 100);var plane = new THREE.Mesh(planeGeometry, cubeMaterial);// 设置平面位置并旋转plane.rotation.x = -0.5 * Math.PI;plane.position.x = 0;plane.position.z = -5;plane.position.y = -5;scene.add(plane);}function renderScene() {orbit.update(); // 拖动TWEEN.update();if (cloud) {var vertices = cloud.geometry.vertices;vertices.forEach(function(v) {v.y = v.y - (v.velocityY);v.x = v.x - (v.velocityX);if (v.y <= 0) v.y = 60;if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1;});cloud.geometry.verticesNeedUpdate = true;}// 使用requestAnimationFrame函数进行渲染requestAnimationFrame(renderScene);renderer.render(scene, camera);}// 渲染的场景renderer.render(scene, camera);}window.onload = init;// 随着窗体的变化修改场景function onResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}// 监听窗体调整大小事件window.addEventListener('resize', onResize, false);</script></body>
</html>

需要完整代码请留言或者联系我

Threejs实现下雨,下雪,阴天,晴天,火焰相关推荐

  1. canvas 让你呼风唤雨,下雨下雪效果

    前端如何呼风唤雨 Canvas 等于什么?   = html5 =js = 取代flash =  你可以即见即所得向别人装逼!没错 进入 canvas 的权力游戏吧! 起初我创造了canvas . 我 ...

  2. cesium,实现下雨下雪效果切换

    honey们,一起来学习cesium天气效果吧^^ 本篇文章实现的是简单的HTML页面在线显示,用其他框架的改一下就可以啦 1.CDN引入 <script src='https://cdn.bo ...

  3. cesium实现下雨下雪特效

    页面效果 使用着色器实例特效 下雨特效着色器 // 下雨特效 rain () {removeStage();var e = new Cesium.PostProcessStage({name: &qu ...

  4. iOS实现“下雨下雪”动画效果和“烟花”动画效果

    "下雨"的动画效果 一.效果展示 二.实现流程 设置背景 func setupUI() {self.imageView = UIImageView.init()self.image ...

  5. HMM(马尔科夫过程及隐马尔科夫过程)

    转载地址(http://blog.csdn.net/xinzhangyanxiang/article/details/8522078) 学习概率的时候,大家一定都学过马尔科夫模型吧,当时就觉得很有意思 ...

  6. 隐马尔科夫模型(HMM)及其扩展

    转载自:(http://blog.csdn.net/xinzhangyanxiang/article/details/8522078) 学习概率的时候,大家一定都学过马尔科夫模型吧,当时就觉得很有意思 ...

  7. 白噪音和粉红噪音煲机_白噪音真的有助于睡眠?这款可以自定义的应用给你答案...

    小时候特别喜欢下雨下雪,因为雨雪之后的空气特别清新好闻,还有一个原因是一到雨雪天气,整个空间便获得了一种安谧,而这种安谧,一般只有晚上才能享受的到. 而现在幸运就幸运在我不需要再等待雨天了,各种各样的 ...

  8. Machine Learning | (5) Scikit-learn的分类器算法-朴素贝叶斯

    Machine Learning | 机器学习简介 Machine Learning | (1) Scikit-learn与特征工程 Machine Learning | (2) sklearn数据集 ...

  9. 推荐系统(1)--splitting approaches for context-aware recommendation

    开篇语: 大一的时候,在实验室老师和师兄的带领下,我开始接触推荐系统.时光匆匆,转眼已是大三,由于大三课甚是少,于是便有了时间将自己所学的东西做下总结.第一篇博客,献给过去三年里带我飞的老师和师兄们, ...

最新文章

  1. ubuntu下docker使用GPU
  2. 使用Transact-SQL进行数据导入导出方法详解
  3. 马尔科夫随机场之图像分割【二】
  4. redis——redis事务相关处理
  5. 移动端点击拉起输入_耐用的筛分式移动破碎站
  6. oracle exception 循环,Oracle Exception In Loop
  7. Tomcat 添加为系统服务 开机自动启动
  8. JetBrains系列WebStorm等中文输入法无法跟随光标的问题的解决办法
  9. 高动态范围图像是什么
  10. 结合XML的数据检索技术
  11. 本地上传文件到服务器
  12. 选择H5响应式网站建设的主要原因
  13. 爬取微信公众号cookie获取与token获取
  14. 数据科学导引上机(5)
  15. 谷歌浏览器安装vue-devtools插件
  16. Sqlite3并发读写注意事项
  17. 苹果电脑重置登录密码
  18. 小白怎么学习python
  19. Win10中的ERDAS 9.2安装(附下载链接)
  20. 真假PSP的一些鉴别方法~~希望对准备入手PSP的玩友有帮助!!

热门文章

  1. Ubuntu搜狗输入法乱码问题
  2. powershell中 find 命令报参数格式不正确
  3. JAVA8线程池THREADPOOLEXECUTOR底层原理及其源码解析
  4. 正确打开adams软件_adams软件在工程机械系统仿真中的应用案例.ppt
  5. 机器学习日记Day4
  6. 安装MySql5-7
  7. 题目1155:鸡兔同笼
  8. VK2C22A替代16C22,是段码低功耗LCD液晶显示驱动芯片/段码液晶驱动IC,44SEG*4COM/40*4,高抗干扰.稳定性强
  9. 如何实现html5页面,自动提示添加到主屏幕
  10. astrolog php,Astrolog星象学软件使用指南(2)