当施加较大的纹理图像的网格的时间three.js所锁式浏览器的主线程显着的时期。让我们看看下面的例子:加载纹理从Web工作在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);
});
我也注意到以下几点:
- 如果新对象不添加到场景
- 变化的几何形状不会发生线程锁定对象不会导致锁定
- 如果一个新的对象与从现有对象借来的材料(这已是在场景中)创建将不会造成锁定
- 现有对象分配一个新的材料(这已经是在现场)会导致锁定
我的结论是,three.js所做一些工作,在材料的指向它添加到场景的点。其结果是缓存并稍后重新使用。
的问题是,如果这项工作能以某种方式被卸载到网络工作者,使主线程不会被锁定呢?
工人看起来是这样的:
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);
});
能像这样做呢?
您可以使用浏览器调试工具获取此加载操作的时间线快照。例如在Chrome中,您将看到方法X需要Y秒。这应该告诉你瓶颈在哪里。如果是THREE.js将纹理发送到GPU的地方,那么除了使用较小的纹理,或者将其分割为多个材质之外,您可能无法做任何事情。 – TheJim01