美文网首页
Three.js 初步

Three.js 初步

作者: ITtian | 来源:发表于2017-05-13 18:06 被阅读247次

    HTML5有强大的动画效果,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,但一直没有没有涉及到游戏方面的业务,所以对这方面知之甚少,感觉自己损失了一大片宝藏一样,好心疼,three.js,是对webGL 的一个封装,使我们不必纠结于一些数学问题(比如旋转啊,线性代数的求解啊,说实话,我真的忘了怎么解)

    第一步,加载three.js,一般稍微有点名气的工具,都是有cdn的,threejs有个缺点,就是版本更新太快,都r83了,现在实现一个入门的雪花效果

    <script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>
    

    第二步,three.js中主要有三个概念,场景,相机,渲染器,初始化一下

    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000);
    camera.position.z = 100;
    
    scene = new THREE.Scene();
    renderer = new THREE.WebGLRenderer({alpha: true});
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    

    第三步,既然是雪花效果,所以需要一张图片,three.js中,一般这样处理,先得到一个纹理,然后得到材料,然后得到一个平面,最后将这个平面加入场景中,每一级都有依赖

    // 纹理,应用于一个表面,或者作为一个反射或折射贴图。
            textureLoader = new THREE.TextureLoader();
            map  = textureLoader.load('snow2.jpg');
            // 传入纹理,得到材料
            material = new THREE.SpriteMaterial({map: map});
            for ( i = 0; i < amount; i ++ ){
                // 精灵平面
                var particle = new THREE.Sprite( material );
                var randomScale = randomRange(20,40)
    
                particle.position.x = randomRange(-1000, 800);
                particle.position.y = randomRange(-1000, 1200);
                particle.position.z = randomRange(-1000, 1000);
                particle.scale.x = particle.scale.y = particle.scale.z = randomScale;
                particle.v = new THREE.Vector3(0, -fallSpeen, 0);
                particle.v.z = (1 * randomRange(-1, 1));
                particle.v.x = (1 * randomRange(-1, 1));
    
                particles.push(particle);
    //将平面加入场景中
                scene.add( particle );
            }
    

    第四步,将render生成的canvas插入到页面中

    container.appendChild(renderer.domElement);
    

    第五步,将场景,和相机传递到渲染器中,渲染出来

    renderer.render( scene, camera );
    

    第六步:不断的调整平面的位置,然后重复第五步,此处写一个方法,requestAnimationFrame可以按照浏览器最高的频率绘制,同时切换到别的tab页时,会停止计算,但是settimeout不会。

    function animate() {
            requestAnimationFrame(animate);
            render();
        }
    

    完整代码,直接copy就可以使用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>
    </head>
    <body>
    
    <script>
        console.log(THREE)
        var container, camera, scene, renderer, particles = [], material, map, textureLoader;
        var halfX = window.innerWidth / 2;
        var halfY = window.innerHeight / 2;
        var mouseX = 0, mouseY = 0;
        var fallSpeen = 2;
        var amount = 1000;
    
        // 返回一个范围内内的随机数
        function randomRange(min, max) {
            return ((Math.random() * (max - min)) + min);
        }
        
        function init() {
            container = document.createElement('div');
            document.body.appendChild(container);
            // 相机
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000);
            camera.position.z = 100;
            // 场景
            scene = new THREE.Scene();
            // 纹理,应用于一个表面,或者作为一个反射或折射贴图。
            textureLoader = new THREE.TextureLoader();
            map  = textureLoader.load('snow2.jpg');
            // 传入纹理,得到材料
            material = new THREE.SpriteMaterial({map: map});
            for ( i = 0; i < amount; i ++ ){
                // 精灵平面
                var particle = new THREE.Sprite( material );
                var randomScale = randomRange(20,40)
    
                particle.position.x = randomRange(-1000, 800);
                particle.position.y = randomRange(-1000, 1200);
                particle.position.z = randomRange(-1000, 1000);
                particle.scale.x = particle.scale.y = particle.scale.z = randomScale;
                particle.v = new THREE.Vector3(0, -fallSpeen, 0);
                particle.v.z = (1 * randomRange(-1, 1));
                particle.v.x = (1 * randomRange(-1, 1));
    
                particles.push(particle);
                scene.add( particle );
            }
    
            renderer = new THREE.WebGLRenderer({alpha: true});
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
    
            // renderer.domElement 就是canvas
            container.appendChild(renderer.domElement);
            animate();
        }
    
        function animate() {
            requestAnimationFrame(animate);
            render();
        }
    
        function render() {
            for(var i = 0; i < particles.length; i++){
                var particle = particles[i];
                var pp = particle.position;
    
                pp.add(particle.v);
                // 调整位置,从左边出去的,从右边回来
                if(pp.y < -1000) pp.y = 1000;
                if(pp.x > 1000) pp.x = -1000;
                else if(pp.x < -1000) pp.x = 1000;
                if(pp.z > 1000) pp.z=-1000;
                else if(pp.z < -1000) pp.z = 1000;
            }
    
            // 重新渲染
            renderer.render( scene, camera );
        }
    
        init()
    </script>
    </body>
    </html>
    

    最后附上几个链接:
    three.js 中文文档
    three.js Github
    three.js 实例效果

    相关文章

      网友评论

          本文标题:Three.js 初步

          本文链接:https://www.haomeiwen.com/subject/jdaxxxtx.html