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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30100043/article/details/85163265

之前一直想研究一下web Workers多线程处理,页面中使用web Workers大家可以转弯去web Workers多线程看一下如何使用。
这篇文章主要实现的是Three.js和web Workers一次简单的结合。本来想实现通过web Workers实现加载的,可惜Three.js使用了过多的window方法,而web Workers线程内是无法获取到window对象,所以,这次实现案例就写的是在web Workers里面更新当前场景内所有立方体的位置信息的方法。
虽然这次的案例比较简单,只是开篇的,后期我们可以将运算工作量很大的代码放到多线程内,主线程的交互不受影响,web Workers只要将计算得出的结果返回主线程即可。
在这里插入图片描述
小姐姐模型是页面正常的案例
在模型加载完成时,将创建一个web Workers线程,在worker线程内处理周围立方体的位置。
主要不同的代码就是预创建了一个供worker处理的数组:

        //生成一千个立方体
        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);

和在模型加载成功后,我们创建worker对象:

        //创建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;
                }
            }
        });

然后worker对象在接收到处理好的y轴坐标信息,再将每个立方体的位置修改一下。

接下来就是worker线程内的逻辑运算,案例运算也比较简单,就是数组创建的时候都设置了一个速度,每一帧都加上这一个速度然后到一定高度以后,再返回默认位置:

onmessage = function (e) {
    let arr = e.data;
    //更新数组位置信息
    setInterval(function () {
        for (let i = 0; i < arr.length; i++) {
            arr[i].y += arr[i].speed;
            if (arr[i].y >= 80) {
                arr[i].y = -3;
            }
        }
        postMessage(arr);
    }, 1000 / 60);
};

每次数组运算完成后,再通过postMessage方法传递到主线程,供three使用。

案例地址:https://www.wjceo.com/blog/threejs2/2018-12-21/182.html

猜你喜欢

转载自blog.csdn.net/qq_30100043/article/details/85163265