Three.js实现的粒子系统

前端开发 同时被 2 个专栏收录
52 篇文章 1 订阅
5 篇文章 1 订阅

用Three.js实现的粒子系统,主要是用图片做的纹理,有下雨、下雪、星空等效果,很多参数可以自己控制。




    
   
    
   
     href="index.css" rel="stylesheet" type="text/css">
    
    <script type="text/javascript" src="build/three.js"></script>
    <script type="text/javascript" src="libs/stats.min.js"></script>
    <script type="text/javascript" src="libs/dat.gui.min.js"></script>
    
   
    <script type="text/javascript">
        var scene, camera, renderer, spot1, stats;
        var cloud, controls;

        function init() {
            stats = new initStats();//初始化检测帧频
            scene = new THREE.Scene();//场景
            scene.fog = new THREE.Fog(0xffffff, 0.015, 100);
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);//透视相机
            camera.position.set(0, 0, 150);//相机位置
            scene.add(camera);//add到场景中

            spot1 = new THREE.SpotLight(0xffffff, 3000);//点光源
            spot1.position.set(100, 200, 100);
            scene.add(spot1);

            renderer = new THREE.WebGLRenderer({antialias: true,alpha:true});//渲染
            renderer.setClearColor(0x00000);//设置可以认为是底图的颜色
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.shadowMap.enable = true;//shadow,阴影,表明能渲染阴影
            document.getElementById('webGL_output').appendChild(renderer.domElement);//将渲染Element添加到Dom中

            /*
            控制器,用于选择创建粒子的数量大小等
            */
            controls = new function () {
                this.createNums = 5000;//默认创建5000个粒子
                this.size = 4;//默认大小
                this.transparent = true;//透明的
                this.opacity = 0.6;//不透明
                this.vertexColors = true;//坐标点集颜色
                this.color = 0xffffff;//控制器本身颜色
                this.sizeAttenuation = true;//如果为false 则所有粒子拥有相同的尺寸。无论距离相机多远
                this.rotateSystem = true;//是否旋转
                this.rotateSpeed = 1;//上下速度
                this.fog=true;//是否雾化
                this.type="img/snow.png";//纹理图片
                this.bcColor=0x00000;//背景颜色
                this.windSpeed=1;//左右速度
                this.lifeTime=2000;//生命周期
                this.redraw = function () {
                    if (scene.getObjectByName('particles')) {
                        scene.remove(scene.getObjectByName('particles'));
                    }//存在则清除,然后重制
                    renderer.setClearColor(controls.bcColor);
                    createParticles(
                        controls.type,
                        controls.createNums,
                        controls.size,
                        controls.transparent,
                        controls.opacity,
                        controls.vertexColors,
                        controls.sizeAttenuation,
                        controls.color,
                        controls.fog
                    );
                }
            };

            var gui = new dat.GUI();
            gui.add(controls, 'createNums', 1, 10000).onChange(controls.redraw);//创建粒子数由1到10000个
            gui.add(controls, 'size', 0, 10).onChange(controls.redraw);//大小0——10
            gui.add(controls, 'transparent').onChange(controls.redraw);
            gui.add(controls, 'opacity', 0, 1).onChange(controls.redraw);
            gui.add(controls, 'vertexColors').onChange(controls.redraw);
            gui.addColor(controls, 'color').onChange(controls.redraw);
            gui.add(controls, 'sizeAttenuation').onChange(controls.redraw);
            gui.add(controls, 'rotateSystem').onChange(controls.redraw);
            gui.add(controls, 'rotateSpeed', 0, 5).onChange(controls.redraw);
            gui.add(controls, 'fog').onChange(controls.redraw);
            gui.add(controls, 'type',{雪: "img/snow.png", 雨:"img/rain.png",星星:"img/star.png"}).onChange(controls.redraw);
            gui.addColor(controls, 'bcColor').onChange(controls.redraw);
            gui.add(controls, 'windSpeed',-5.0,5.0).onChange(controls.redraw);
            gui.add(controls, 'lifeTime',1000,5000).onChange(controls.redraw);
            controls.redraw();
            render();

        }
        /*
        将检测帧频显示在左上方。
        */
        function initStats() {
            var stats = new Stats();
            stats.setMode(0);

            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';
            document.getElementById('stats_output').appendChild(stats.domElement);
            return stats;
        }

        /*
        该函数用于生成粒子
        */
        function createParticles(type,createNums, size, transparent, opacity, vertexColors, sizeAttenuation, color,fog) {
            if(cloud){scene.remove(cloud)}
            //几何体
            var geom = new THREE.Geometry();

            var texture = THREE.ImageUtils.loadTexture(type, null, function (t) {
            });
            //粒子系统材质,
            var material = new THREE.PointsMaterial({
                size: size,
                transparent: transparent,
                opacity: opacity,
                vertexColors: vertexColors,
                sizeAttenuation: sizeAttenuation,
                blending:true,
                color: color,
                fog:fog,
                map:texture,
                blending:THREE.AdditiveBlending
            });

            var range = 500;
            for (var i = 0; i < createNums; i++) {
                var particle = new THREE.Vector3(Math.random() * range - range / 2,
                    Math.random() * range - range / 2, Math.random() * range - range / 2);
                geom.vertices.push(particle);//点加入
                var color = new THREE.Color(0x00ff00);//默认,关于颜色的设置只在vertexColors设置为true时使用
                color.setHSL(color.getHSL().h, color.getHSL().s, Math.random() * color.getHSL().l);
                geom.colors.push(color);//颜色加入
            }
            cloud = new THREE.Points(geom, material);//粒子云系统
            cloud.name = 'particles';//命名名字,在重绘的时候使用
            scene.add(cloud);
        }

        var startTime = Date.now();

        function render() {
            stats.update();
            if (Date.now() - startTime > controls.lifeTime) {
                createParticles(
                    controls.type,
                    controls.createNums,
                    controls.size,
                    controls.transparent,
                    controls.opacity,
                    controls.vertexColors,
                    controls.sizeAttenuation,
                    controls.color,
                    controls.fog
                );
                startTime=Date.now();
            }
                /**
                 * 让粒子下落,超出摄像机范围之前重设位置
                 * @type {number}
                 */
                cloud.position.y-=controls.rotateSpeed;
                cloud.position.x-=controls.windSpeed;
                if(cloud.position.y<-200){
                    cloud.position.y=0;
                }
                if(cloud.position.x<-200||cloud.position.x>200){
                    cloud.position.x=0;
                }
            requestAnimationFrame(render);//html5的方法,用于绘制一次动画帧
            renderer.render(scene, camera);
        }
        window.onload = init;
    </script>



   
<script src="MouseControl.js"></script>


  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:点我我会动 设计师:我叫白小胖 返回首页

打赏作者

GIS开发者

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值