使用 Three.js 加载多个 obj+mtl 会崩溃,尤其是在 iOS 上
Multiple obj+mtl loading with Three.js crashes especially on iOS
我想使用 Three.js 和以下代码加载多个 obj+mtl 文件。它适用于一个或两个 obj 数据。但是当我尝试加载多个 OBJ(超过三个)时,它会崩溃,尤其是在 iOS.
上
obj数据较小,一共6MB。如果我在加载后克隆该对象,它甚至可以处理十个对象,但如果在 iOS 上多次使用 THREE.OBJMTLLoader,它就会崩溃。
我找不到加载多个 obj 文件的好例子。对于多个 OBJ,有什么我应该关心的吗?
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"></head>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/loaders/MTLLoader.js"></script>
<script src="http://threejs.org/examples/js/loaders/OBJMTLLoader.js"></script>
<body>
<div id="canvas_frame"></div>
<script>
var canvasFrame, scene, renderer, camera;
canvasFrame = document.getElementById('canvas_frame');
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
canvasFrame.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set(50,50,50);
camera.lookAt( {x: 0, y: 0, z: 0} );
var ambient = new THREE.AmbientLight(0xFFFFFF);
scene.add(ambient);
function animate() {
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
function loadObjMtl(objUrl, mtlUrl, url, x, y, z){
var loader = new THREE.OBJMTLLoader();
loader.crossOrigin = 'anonymous';
loader.load( objUrl, mtlUrl,
function ( object ) {
object.url = url;
object.position.set(x,y,z);
scene.add ( object );
});
}
objUrl = "http://test2.psychic-vr-lab.com/temp/mesh_reduced.obj";
mtlUrl = "http://test2.psychic-vr-lab.com/temp/mesh_reduced.mtl";
loadObjMtl(objUrl,mtlUrl,"",0,0,0);
loadObjMtl(objUrl,mtlUrl,"",20,20,0);
loadObjMtl(objUrl,mtlUrl,"",40,20,0);
loadObjMtl(objUrl,mtlUrl,"",60,0,0);
animate();
</script>
</body>
</html>
您的 iOS 设备上的显存可能 运行 不足。
您使用的纹理文件很大,例如这个是 4096x4096 http://test2.psychic-vr-lab.com/temp/tex_0.jpg
未压缩为供 OpenGL 使用的原始位图,然后占用大量内存(我认为是数十兆,RGB 的 4096 * 4096 * 3 大约为 50MB)。
使用较小分辨率的图片。并且另外使用可以在压缩格式中使用的纹理格式,在 iOS PVRTC 上,在 https://github.com/mrdoob/three.js/pull/5337 ("PVRTC support in examples")[=12 中添加了对 three.js 的支持=]
克隆之所以有效,是因为您可以为许多对象重复使用相同的纹理 -- 大图像仅在内存中出现一次。如果他们都使用相同的图像,那当然是您想要的。但是,如果您需要为各种对象使用不同的图像,那么您需要减少它们的内存消耗。
我想使用 Three.js 和以下代码加载多个 obj+mtl 文件。它适用于一个或两个 obj 数据。但是当我尝试加载多个 OBJ(超过三个)时,它会崩溃,尤其是在 iOS.
上obj数据较小,一共6MB。如果我在加载后克隆该对象,它甚至可以处理十个对象,但如果在 iOS 上多次使用 THREE.OBJMTLLoader,它就会崩溃。
我找不到加载多个 obj 文件的好例子。对于多个 OBJ,有什么我应该关心的吗?
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"></head>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/loaders/MTLLoader.js"></script>
<script src="http://threejs.org/examples/js/loaders/OBJMTLLoader.js"></script>
<body>
<div id="canvas_frame"></div>
<script>
var canvasFrame, scene, renderer, camera;
canvasFrame = document.getElementById('canvas_frame');
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
canvasFrame.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set(50,50,50);
camera.lookAt( {x: 0, y: 0, z: 0} );
var ambient = new THREE.AmbientLight(0xFFFFFF);
scene.add(ambient);
function animate() {
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
function loadObjMtl(objUrl, mtlUrl, url, x, y, z){
var loader = new THREE.OBJMTLLoader();
loader.crossOrigin = 'anonymous';
loader.load( objUrl, mtlUrl,
function ( object ) {
object.url = url;
object.position.set(x,y,z);
scene.add ( object );
});
}
objUrl = "http://test2.psychic-vr-lab.com/temp/mesh_reduced.obj";
mtlUrl = "http://test2.psychic-vr-lab.com/temp/mesh_reduced.mtl";
loadObjMtl(objUrl,mtlUrl,"",0,0,0);
loadObjMtl(objUrl,mtlUrl,"",20,20,0);
loadObjMtl(objUrl,mtlUrl,"",40,20,0);
loadObjMtl(objUrl,mtlUrl,"",60,0,0);
animate();
</script>
</body>
</html>
您的 iOS 设备上的显存可能 运行 不足。
您使用的纹理文件很大,例如这个是 4096x4096 http://test2.psychic-vr-lab.com/temp/tex_0.jpg
未压缩为供 OpenGL 使用的原始位图,然后占用大量内存(我认为是数十兆,RGB 的 4096 * 4096 * 3 大约为 50MB)。
使用较小分辨率的图片。并且另外使用可以在压缩格式中使用的纹理格式,在 iOS PVRTC 上,在 https://github.com/mrdoob/three.js/pull/5337 ("PVRTC support in examples")[=12 中添加了对 three.js 的支持=]
克隆之所以有效,是因为您可以为许多对象重复使用相同的纹理 -- 大图像仅在内存中出现一次。如果他们都使用相同的图像,那当然是您想要的。但是,如果您需要为各种对象使用不同的图像,那么您需要减少它们的内存消耗。