欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

threeJS 创建漫天飘雪

程序员文章站 2022-05-26 19:15:46
...

本例来源官方案例

效果图

threeJS 创建漫天飘雪

总体步骤

① 创建场景
② 创建相机
③ 创建物体
④创建渲染器

html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body{
            padding: 0;
            margin: 0;
            overflow: hidden;
        }

    </style>
</head>
<body>
<div id="container">

</div>
<script type="module">


</script>
</body>
</html>


导入文件,创建全局变量和函数

  import * as THREE from "./js/three.module.js";
    import {OrbitControls} from "./js/OrbitControls.js";
    import Stats from './js/stats.module.js';
  
    let renderer,scene,camera,spotLight,status;

    action();
    function action() {
        onload();
        run();
    }
      function onload(){

     }
     function run()
     {
     }
     function onResize()
     {
     }


①创建场景

onload函数中

 let container=document.getElementById("container");//获取container

        scene=new THREE.Scene();//创建场景
        scene.fog = new THREE.FogExp2( 0x000000, 0.0008 );//设置雾

②创建相机

onload函数中

        camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,10000);
        camera.position.set(20,30,25);//创建相机并设置位置
        camera.lookAt(scene.position);

③创建物体

onload函数中

  let spriteGeometry=new THREE.BufferGeometry();//生成几何体
        let spriteTextureLoad=new THREE.TextureLoader();//创建纹理加载器

        let spriteTexture1=spriteTextureLoad.load("./img/snowflake1.png");
        let spriteTexture2=spriteTextureLoad.load("./img/snowflake2.png");
        let spriteTexture3=spriteTextureLoad.load("./img/snowflake3.png");
        let spriteTexture4=spriteTextureLoad.load("./img/snowflake4.png");
        let spriteTexture5=spriteTextureLoad.load("./img/snowflake5.png");

        let vertices=[];//用于存储随机生成的点

        for(let i=0;i<10000;i++)
        {//随机生成位置
            let x=Math.random()*2000-1000;
            let y=Math.random()*2000-1000;
            let z=Math.random()*2000-1000;
            vertices.push(x,y,z);
        }
       spriteGeometry.addAttribute('position',new THREE.Float32BufferAttribute(vertices,3));//传入顶点数据,类似webgl给position传递数据(其实一样的,就是函数名不同)

        let color1=new THREE.Color();
        color1.setHSL( 0.90, 0.05, 0.5);
        let spriteMaterial1=new THREE.PointsMaterial({size:10,map:spriteTexture1,blending:THREE.AdditiveBlending,transparent:true,color:color1,depthWrite:false});//创建材质
        let sprite1=new THREE.Points(spriteGeometry,spriteMaterial1);
        sprite1.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite1.rotation.y = Math.random() * 6;
        sprite1.rotation.z = Math.random() * 6;
        scene.add(sprite1);

        color1.setHSL(1.0, 0.2, 0.5);
        let spriteMaterial2=new THREE.PointsMaterial({size:20,map:spriteTexture2,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite2=new THREE.Points(spriteGeometry,spriteMaterial2);
        sprite2.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite2.rotation.y = Math.random() * 6;
        sprite2.rotation.z = Math.random() * 6;
        scene.add(sprite2);

        color1.setHSL( 0.95, 0.1, 0.5);
        let spriteMaterial3=new THREE.PointsMaterial({size:15,map:spriteTexture3,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite3=new THREE.Points(spriteGeometry,spriteMaterial3);
        sprite3.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite3.rotation.y = Math.random() * 6;
        sprite3.rotation.z = Math.random() * 6;
        scene.add(sprite3);

        color1.setHSL( 0.80, 0, 0.5);
        let spriteMaterial4=new THREE.PointsMaterial({size:5,map:spriteTexture4,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite4=new THREE.Points(spriteGeometry,spriteMaterial4);
        sprite4.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite4.rotation.y = Math.random() * 6;
        sprite4.rotation.z = Math.random() * 6;
        scene.add(sprite4);

        color1.setHSL( 0.80, 0, 0.5);
        let spriteMaterial5=new THREE.PointsMaterial({size:5,map:spriteTexture5,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite5=new THREE.Points(spriteGeometry,spriteMaterial5);
        sprite5.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite5.rotation.y = Math.random() * 6;
        sprite5.rotation.z = Math.random() * 6;
        scene.add(sprite5);
       

④创建渲染器

onload函数中

  renderer=new THREE.WebGLRenderer({antialias:true});
        renderer.setPixelRatio(window.devicePixelRatio);
        //renderer.shadowMap.enabled=true;//开启阴影
        renderer.gammaInput=true;
        renderer.gammaOutput=true;//inear转gamma
        //renderer.setClearColor(0XEEEEEE);
        //renderer.shadowMap.type=THREE.PCFSoftShadowMap;
        renderer.setSize(window.innerWidth,window.innerHeight);
        container.appendChild(renderer.domElement);

        status=new Stats();//创建频率显示
        container.appendChild(status.dom);//频率挂到左上角
        let contorl=new OrbitControls(camera,renderer.domElement);//添加鼠标滚动缩放,旋转对象
        window.addEventListener('resize',onResize,false);//浏览器大小改变监听

onResize函数中

 function onResize() {
        camera.aspect=window.innerWidth/window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth,window.innerHeight);
    }

run函数中

function run() {
        requestAnimationFrame(run);
        let time = Date.now() * 0.00003;
        for ( let i = 0; i < scene.children.length; i ++ ) {//设置雪花绕Y轴旋转

            let object = scene.children[ i ];

            if ( object instanceof THREE.Points ) {

                object.rotation.y = time * ( i < 4 ? i + 1 : - ( i + 1 ) );

            }

        }
        renderer.render(scene,camera);
        status.update();
    }


总代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body{
            padding: 0;
            margin: 0;
            overflow: hidden;
        }

    </style>
</head>
<body>
<div id="container">

</div>
<script type="module">
    import * as THREE from "./js/three.module.js";
    import {OrbitControls} from "./js/OrbitControls.js";
    import Stats from './js/stats.module.js';
    let renderer,scene,camera,spotLight,status;

    action();
    function action() {
        onload();
        run();
    }
    function onload() {
        let container=document.getElementById("container");//获取container

        scene=new THREE.Scene();//创建场景
        scene.fog = new THREE.FogExp2( 0x000000, 0.0008 );//设置雾

        camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,10000);
        camera.position.set(20,30,25);//创建相机并设置位置
        camera.lookAt(scene.position);



        //let axe=new THREE.AxesHelper(20);
       // scene.add(axe);//辅助工具,用于创建相机时,相机找到合适的位置

        //let ambientLight=new THREE.AmbientLight();
        //scene.add(ambientLight);

        /*spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(0, 5,20);
        spotLight.intensity=2;
        scene.add(spotLight);
        let spotLightMesh=new THREE.Mesh(new THREE.SphereGeometry(0.125,20,20),new THREE.MeshBasicMaterial());
        spotLight.add(spotLightMesh);*/

        //let gridHelper=new THREE.GridHelper(30,20);
        //scene.add(gridHelper);

        let spriteGeometry=new THREE.BufferGeometry();//生成几何体
        let spriteTextureLoad=new THREE.TextureLoader();//创建纹理加载器

        let spriteTexture1=spriteTextureLoad.load("./img/snowflake1.png");
        let spriteTexture2=spriteTextureLoad.load("./img/snowflake2.png");
        let spriteTexture3=spriteTextureLoad.load("./img/snowflake3.png");
        let spriteTexture4=spriteTextureLoad.load("./img/snowflake4.png");
        let spriteTexture5=spriteTextureLoad.load("./img/snowflake5.png");

        let vertices=[];//用于存储随机生成的点

        for(let i=0;i<10000;i++)
        {
            let x=Math.random()*2000-1000;
            let y=Math.random()*2000-1000;
            let z=Math.random()*2000-1000;
            vertices.push(x,y,z);
        }
       spriteGeometry.addAttribute('position',new THREE.Float32BufferAttribute(vertices,3));//传入顶点数据

        let color1=new THREE.Color();
        color1.setHSL( 0.90, 0.05, 0.5);
        let spriteMaterial1=new THREE.PointsMaterial({size:10,map:spriteTexture1,blending:THREE.AdditiveBlending,transparent:true,color:color1,depthWrite:false});//创建材质
        let sprite1=new THREE.Points(spriteGeometry,spriteMaterial1);
        sprite1.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite1.rotation.y = Math.random() * 6;
        sprite1.rotation.z = Math.random() * 6;
        scene.add(sprite1);

        color1.setHSL(1.0, 0.2, 0.5);
        let spriteMaterial2=new THREE.PointsMaterial({size:20,map:spriteTexture2,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite2=new THREE.Points(spriteGeometry,spriteMaterial2);
        sprite2.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite2.rotation.y = Math.random() * 6;
        sprite2.rotation.z = Math.random() * 6;
        scene.add(sprite2);

        color1.setHSL( 0.95, 0.1, 0.5);
        let spriteMaterial3=new THREE.PointsMaterial({size:15,map:spriteTexture3,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite3=new THREE.Points(spriteGeometry,spriteMaterial3);
        sprite3.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite3.rotation.y = Math.random() * 6;
        sprite3.rotation.z = Math.random() * 6;
        scene.add(sprite3);

        color1.setHSL( 0.80, 0, 0.5);
        let spriteMaterial4=new THREE.PointsMaterial({size:5,map:spriteTexture4,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite4=new THREE.Points(spriteGeometry,spriteMaterial4);
        sprite4.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite4.rotation.y = Math.random() * 6;
        sprite4.rotation.z = Math.random() * 6;
        scene.add(sprite4);

        color1.setHSL( 0.80, 0, 0.5);
        let spriteMaterial5=new THREE.PointsMaterial({size:5,map:spriteTexture5,blending: THREE.AdditiveBlending,transparent: true,color:color1,depthWrite:false});
        let sprite5=new THREE.Points(spriteGeometry,spriteMaterial5);
        sprite5.rotation.x = Math.random() * 6;//为了和其他雪花错开位置
        sprite5.rotation.y = Math.random() * 6;
        sprite5.rotation.z = Math.random() * 6;
        scene.add(sprite5);
        console.log(scene);

        renderer=new THREE.WebGLRenderer({antialias:true});
        renderer.setPixelRatio(window.devicePixelRatio);
        //renderer.shadowMap.enabled=true;//开启阴影
        renderer.gammaInput=true;
        renderer.gammaOutput=true;//inear转gamma
        //renderer.setClearColor(0XEEEEEE);
        //renderer.shadowMap.type=THREE.PCFSoftShadowMap;
        renderer.setSize(window.innerWidth,window.innerHeight);
        container.appendChild(renderer.domElement);

        status=new Stats();//创建频率显示
        container.appendChild(status.dom);//频率挂到左上角
        let contorl=new OrbitControls(camera,renderer.domElement);//添加鼠标滚动缩放,旋转对象
        window.addEventListener('resize',onResize,false);//浏览器大小改变监听
    }
    function onResize() {
        camera.aspect=window.innerWidth/window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth,window.innerHeight);
    }

    function run() {
        requestAnimationFrame(run);
        let time = Date.now() * 0.00003;
        for ( let i = 0; i < scene.children.length; i ++ ) {

            let object = scene.children[ i ];

            if ( object instanceof THREE.Points ) {

                object.rotation.y = time * ( i < 4 ? i + 1 : - ( i + 1 ) );

            }

        }
        renderer.render(scene,camera);
        status.update();
    }


</script>
</body>
</html>
相关标签: threejs