106 THREE.JS 实现配合使用web Workers

2018-12-21 15:52:39 人阅读

案例查看有问题?
全屏试试!

案例源代码


                        <!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Three.js 配合 web Workers 案例</title>
    <style type="text/css">
        html, body {
            margin: 0;
            height: 100%;
        }

        canvas {
            display: block;
        }

    </style>
</head>
<body onload="draw();">

</body>
<script src="three.js"></script>
<script src="GLTFLoader.js"></script>
<script src="OrbitControls.js"></script>
<script src="stats.min.js"></script>
<script src="dat.gui.min.js"></script>
<script>
    var renderer, camera, scene, gui, stats, ambientLight, directionalLight, control;

    var mixer, clock = new THREE.Clock();

    function initRender() {
        renderer = new THREE.WebGLRenderer({antialias: true, logarithmicDepthBuffer: true});
        renderer.setSize(window.innerWidth, window.innerHeight);
        //告诉渲染器需要阴影效果
        renderer.shadowMap.enabled = true;
        document.body.appendChild(renderer.domElement);
    }

    function initCamera() {
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 30, 60);
        camera.lookAt(new THREE.Vector3(0, 0, 0));
        scene.add(camera);
    }

    function initScene() {
        scene = new THREE.Scene();
    }

    function initGui() {
        //声明一个保存需求修改的相关数据的对象
        gui = {};

        var datGui = new dat.GUI();
        //将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)
    }

    function initLight() {
        ambientLight = new THREE.AmbientLight("#bbbbbb");
        scene.add(ambientLight);

        directionalLight = new THREE.DirectionalLight("#ffffff");
        directionalLight.position.set(40, 60, 10);

        directionalLight.shadow.camera.near = 1; //产生阴影的最近距离
        directionalLight.shadow.camera.far = 400; //产生阴影的最远距离
        directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置
        directionalLight.shadow.camera.right = 50; //最右边
        directionalLight.shadow.camera.top = 50; //最上边
        directionalLight.shadow.camera.bottom = -50; //最下面

        //这两个值决定生成阴影密度 默认512
        directionalLight.shadow.mapSize.height = 1024;
        directionalLight.shadow.mapSize.width = 1024;

        //告诉平行光需要开启阴影投射
        directionalLight.castShadow = true;

        camera.add(directionalLight);
    }

    function initModel() {

        //底部平面
        var planeGeometry = new THREE.PlaneGeometry(1000, 1000);
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0x333333, side: THREE.DoubleSide});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.y = -.1;
        plane.receiveShadow = true; //可以接收阴影
        scene.add(plane);

        //生成一千个立方体
        let group = new THREE.Group();
        let arr = []; //生成一个速度的数组
        for(let i=0; i<1000; i++){
            group.add(randomCube());
            arr.push({
                speed:Math.random(),
                y:-3
            });
        }
        scene.add(group);

        //创建webWorkers
        if (!window.Worker) {
            alert("你的电脑不支持web Workers");
        }
        let myWorker = new Worker('worker.js');

        //创建gltf加载器
        var loader = new THREE.GLTFLoader();
        loader.load('marie/scene.gltf', function (gltf) {
            console.log(gltf);
            gltf.scene.scale.set(.1, .1, .1);
            gltf.scene.traverse(function (child) {
                if (child.isMesh) {
                    child.frustumCulled = false;
                    child.castShadow = true;
                }
            });
            scene.add(gltf.scene);
            var obj = gltf.scene; //获取到模型对象
            meshHelper = new THREE.SkeletonHelper(obj);
            //scene.add(meshHelper);
            mixer = new THREE.AnimationMixer(obj);
            action = mixer.clipAction(gltf.animations[0]);
            action.play();

            //在模型加载完成后,链接worker线程
            myWorker.postMessage(arr);

            myWorker.onmessage = function (e) {
                for(let i=0; i<e.data.length; i++){
                    group.children[i].position.y = e.data[i].y;
                }
            }
        });



        //随机一个立方体
        function randomCube() {
            let material = new THREE.MeshBasicMaterial({color:0xffffff * Math.random()});
            let boxSize = Math.random()*0.5;
            let geometry = new THREE.BoxGeometry(boxSize, boxSize,boxSize);
            let mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(Math.random()*100-50, -3, Math.random()*100-50);
            mesh.speed = Math.random();
            return mesh;
        }

    }

    function initStats() {
        stats = new Stats();
        document.body.appendChild(stats.dom);
    }

    function initControl() {
        control = new THREE.OrbitControls(camera, renderer.domElement);
        control.target.set(0, 15, 0);
    }

    function render() {

        control.update();

        var time = clock.getDelta();

        if (mixer) {

            mixer.update(time);

        }

        renderer.render(scene, camera);
    }

    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    function animate() {
        //更新控制器
        render();

        //更新性能插件
        stats.update();

        requestAnimationFrame(animate);
    }

    function draw() {
        initGui();
        initRender();
        initScene();
        initCamera();
        initLight();
        initModel();
        initStats();

        initControl();

        animate();
        window.onresize = onWindowResize;
    }
</script>
</html>
展开内容

联系我们

一个人的力量不如两个人的,两个人的力量不如一群人的。欢迎加入大家庭一起共同学习,共同进步。

查看更多