Three.js 项目导致移动设备崩溃

Dil*_*ael 4 javascript three.js

我一直在开发一个 Three.js 项目来尝试学习这个框架。得到了一个基本模型,在桌面浏览器上运行良好,但在移动设备上会反复崩溃。我将项目上传到我的服务器http://trideesneaker.404vanity.com/

有什么方法可以针对移动设备进行优化吗?我在 iPhone 和 iPad 上尝试了 chrome 和 safari。

代码本身:

(function() {

var scene, camera, renderer;
var geometry, material, mesh, sneaker;

init();
animate();

function init() {

    scene = new THREE.Scene();
    var WIDTH = window.innerWidth,
        HEIGHT = window.innerHeight;

        var ambient = new THREE.AmbientLight( 0x444444 );
                scene.add( ambient );

    camera = new THREE.PerspectiveCamera( 3, WIDTH / HEIGHT, 1, 20000 );
    camera.position.z = 1000;



    window.addEventListener('resize', function() {
      var WIDTH = window.innerWidth,
          HEIGHT = window.innerHeight;
      renderer.setSize(WIDTH, HEIGHT);
      camera.aspect = WIDTH / HEIGHT;
      camera.updateProjectionMatrix();
    });

    geometry = new THREE.BoxGeometry( 200, 200, 200 );
    material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );

    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );


    // prepare loader and load the model
    var oLoader = new THREE.OBJMTLLoader();
    oLoader.load('models/sneaker.obj', 'models/sneaker.mtl', function(object) {

      object.scale.set(1, 1, 1);
      object.rotation.y = 600;
      object.rotation.z= 600;
      sneaker = object;
      scene.add(sneaker);
    });


  // var loader = new THREE.OBJLoader();
  // loader.load('models/sneaker.obj', function(object) {
  //   sneaker = object;
  //   sneaker.scale.set(1,1,1);
  //   sneaker.rotation.y = 600;
  //   sneaker.rotation.z= 600;
  //   scene.add(sneaker);

  // });





    renderer = new THREE.WebGLRenderer();
    renderer.setSize( WIDTH, HEIGHT );

    renderer.setClearColor(0x333F47, 1);


    var light = new THREE.PointLight(0xffffff);
    light.position.set(-100,200,100);
    scene.add(light);

    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;
    sneaker.rotation.x += 0.01;
    sneaker.rotation.y += 0.02;


    renderer.render( scene, camera );

}

})();
Run Code Online (Sandbox Code Playgroud)

Atr*_*sis 6

首先对你的js进行评论:typeof sneaker !== 'undefined'在要求旋转网格之前检查渲染循环中是否存在,在加载它之前会产生错误。

你的场景崩溃是因为你使用了太详细的材质,例如我可以看到 4096x4096 的凹凸贴图。它极大地增加了桌面上的帧渲染时间,并且可能是页面在移动设备上无响应的原因:片段着色器计算变得太大。

然而,完全删除那些你花时间处理的细节将是一种耻辱。你可以做的就是在你的js中添加一个设备检测器。您可以使用它在桌面和移动设备上显示两种不同的模型。

但您还可以带来进一步的重要改进。因为它们是我原来帖子的一部分,所以我让它们在那里:):

  1. 调整纹理的大小。您使用的是两个 4.5MB 的 4096 x 4096 jpg,这很重(请注意,最近发布的支持 webgl 的智能手机只有500Mo RAM)。此外,你几乎没有什么细节可以证明这一点。您可以更改 uv 以减少很多没有细节的部分,并且可能将图片大小调整为 512x512。最后,使用 JPG 压缩器,可以减轻 70-80% 的重量。根据您的图片,PNG 也可能是更好的选择。设备的 GPU 内存仍然是其他东西,如果您仍然需要提高性能,您可以在脚本中检查客户端是否支持针对 GPU 内存进行优化的 .pvr 或 .ktx 纹理格式。

  2. 使您的可视化不适合移动设备的一个重要问题是您有... 23 个渲染调用,因为您使用了 15 个纹理和 23 个几何图形。

这意味着,对于每一帧,您必须在最终帧渲染之前绑定 23 个不同的几何图形。某些移动 CPU-GPU 组合无法每秒执行 60 次。对于普通移动设备,不要计划超过 10 次渲染调用。这意味着更少的几何形状和更少的材料。合并。

我没有详细检查你的 .obj 文件来了解你最终如何获得 23 个几何图形,也没有了解你的 13 个纹理来自哪里,由你决定。

当然,商店中的许多 3D 应用程序 (OpenGL) 都有超过 23 个对象。但商店了解这些应用程序,也了解您的手机,因此他们可以完成兼容性工作并将应用程序隐藏到低设备上。

以下是检查场景中的渲染调用、几何图形和材质的提示:在主函数中,设置 后renderer,在窗口对象中包含指向它的指针window.renderer = renderer。现在,在控制台运行时,加载资源后,键入renderer.info。它将在对象中返回这些数据。