当将大型纹理图像应用于网格并保持一段时间时,Three.js会锁定浏览器的主线程。让我们考虑以下示例:
var texLoader = new THREE.TextureLoader();
texLoader.load('someLargeTexture.jpg', function(texture) {
var geometry = new THREE.SphereGeometry(10, 32, 32);
var material = new THREE.MeshBasicMaterial({map: texture});
var sphere = new THREE.Mesh(geometry, material);
// adding the object to the scene will lock up the browser's main thread
scene.add(sphere);
});
我还注意到以下几点:
- 如果新对象未添加到场景中,则不会发生线程锁定
- 更改对象的几何形状不会导致锁定
- 如果使用从已经在场景中的对象借用的材质创建新对象,则不会导致锁定
- 将新材质分配给已经在场景中的对象(该对象已经存在)将会导致锁定
问题是,是否可以将这些工作转移到Web Worker中,以使主线程不会被锁定?
Worker可能看起来像这样:
var texLoader = new THREE.TextureLoader();
texLoader.load('someLargeTexture.jpg', function(texture) {
var material = new THREE.MeshBasicMaterial({map: texture});
// ... long-running work goes here ...
// adding the object to the scene will lock up the browser's main thread
self.postMessage({
msg: 'objectCreated',
material: material.toJson(), // converting material to JSON
});
});
然后在主线程中我们可以这样做:
var worker = new Worker('worker.js');
worker.addEventListener('message', function(ev) {
var geometry = new THREE.SphereGeometry(10, 32, 32);
// converting JSON back to material object
var material = MaterialLoader.prototype.parse( ev.data.material );
// this should't lock-up the main thread
var sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
});
能否实现这样的功能?