使用WebWorker合并几何?

时间:2013-06-03 19:28:32

标签: merge geometry three.js web-worker

任何人都知道是否可以在Web worker中合并一组多维数据集几何并将其传递回主线程?认为这可以减少合并大量立方体时的滞后。

Three.JS在Web工作者中是否正常工作,如果确实如此,是否可以(并且更快)执行此操作?不确定是否将几何体向后传递所需的时间与正常合并一样长。

目前我正在使用定时的 for 循环来减少延迟:

// This array is populated by the server and contains the chunk position and data (which I do nothing with yet).
var sectionData = data.secData;

var section = 0;
var tick = function() {
    var start = new Date().getTime();
    for (; section < sectionData.length && (new Date().getTime()) - start < 1; section++) {
        var sectionXPos = sectionData[section][0] * 10;
        var sectionZPos = sectionData[section][1] * 10;
        var combinedGeometry = new THREE.Geometry();

        for (var layer = 0; layer < 1; layer++) { // Only 1 layer because of the lag...
            for (var x = 0; x < 10; x++) {
                for (var z = 0; z < 10; z++) {
                    blockMesh.position.set(x-4.5, layer-.5, z-4.5);
                    blockMesh.updateMatrix();
                    THREE.GeometryUtils.merge(combinedGeometry, blockMesh);
                }
            }
        }

        var sectionMesh = new THREE.Mesh(combinedGeometry, grassBlockMat);
        sectionMesh.position.set(sectionXPos, 0, sectionZPos);
        sectionMesh.matrixAutoUpdate = false;
        sectionMesh.updateMatrix();
        scene.add(sectionMesh);
    }
    if (section < sectionData.length) {
        setTimeout(tick, 25);
    }
};
setTimeout(tick, 25);

使用Three.JS rev59-dev。

合并的多维数据集以块的形式组成地形,此刻(由于滞后)每个块只有一层。

任何提示将不胜感激!感谢。

1 个答案:

答案 0 :(得分:3)

THREE.JS不适用于网络工作者,但是您可以复制您需要在主线程和网络工作者中工作的库的那些部分。

您的第一个问题是您无法将几何对象本身发送回主线程。

由于web worker onmessage变量传递只能通过发送JSON(不是javascript对象)或ArrayBuffers的引用来实现,所以你必须将几何解码到每个float,将它打包在ArrayBuffer中,然后发送一个引用到主线程。

请注意,这些被称为可转移对象,一旦发送,它们将在它们来自的webworker /主线程中被清除。

请点击此处了解更多详情:

http://www.html5rocks.com/en/tutorials/workers/basics/

https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers

以下是将位置顶点打包到物理类型系统的数组中的示例:

//length * 3 axes * 4 bytes per vertex
var posBuffer = new Float32Array(new ArrayBuffer(len * 3 * 4));

//in a loop

//... do hard work

posBuffer[i * 3] = pos.x; //pos is a threejs vector
posBuffer[i * 3 + 1] = pos.y;
posBuffer[i * 3 + 2] = pos.z;

//after loop send buffer to main thread
self.postMessage({posBuffer:posBuffer}, [posBuffer.buffer]);

我在我的网络工作者中复制了THREE.JS矢量类,并删除了所有我不需要的方法来保持它的美观和精益。

仅供参考,它并不慢,而且对于像n-body碰撞这样的东西来说效果很好。

主线程向Web工作者发送命令,告诉它运行更新,然后侦听响应。有点像常规线程中的生产者消费者模型。