2

Anyone know if it's possible to merge a set of cube geometries in a web worker and pass it back to the main thread? Was thinking this could reduce the lag when merging large amounts of cubes.

Does Three.JS work okay in a web worker, and if it does, would it be possible (and faster) to do this? Not sure if passing the geometry back would take just as long as merging it normally.

At the moment I'm using a timed for loop to reduce the lag:

// 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);

Using Three.JS rev59-dev.

Merged cubes make up the terrain in chunks, and at the moment (due to the lag) each chunk only has 1 layer.

Any tips would be appreciated! Thanks.

4

1 回答 1

3

THREE.JS 不能在 web worker 中工作,但是您可以复制库中需要在主线程和 web worker 中工作的部分。

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

由于 web worker onmessage 变量传递只能通过发送 JSON 副本(不是 javascript 对象)或对 ArrayBuffers 的引用来工作,因此您必须将几何图形解码为每个浮点数,将其打包在 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 体碰撞这样的东西效果很好。

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

于 2013-06-18T15:04:07.737 回答