本文介绍了Three.js 项目导致手机崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究一个 Three.js 项目来尝试学习该框架.有一个浮动的基本模型,它在桌面浏览器上运行良好,但在移动设备上会反复崩溃.我将项目上传到我的服务器 http://threedeesneaker.404vanity.com/

I've been working on a three.js project to try and learn the framework. Got a basic model floating around that works fine on the desktop browser but will crash repeatedly on mobile. I uploaded the project on my server http://threedeesneaker.404vanity.com/

有没有办法针对移动设备优化此功能?我为 iPhone 和 iPad 尝试了 chrome 和 safari.

Is there any way to optimize this for mobile devices? I tried both chrome and safari for iPhone and iPad.

它自己的代码:

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

}

})();

推荐答案

首先对您的 js 发表评论:在要求旋转您的渲染循环之前检查 typeof sporter !== 'undefined'网格,在加载之前会产生错误.

First a comment on your js : check if typeof sneaker !== 'undefined' in your render loop before asking to rotate your mesh, before loading it generates errors.

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

Your scene crashes because you are using too detailed materials, I can see a 4096x4096 bump map for instance. It strongly increases frame rendering time on desktop and is probably the reason why the page is irresponsive on mobile : the fragment shader computations become too big.

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

However it would be a shame to completly delete those details you spent time on. What you can do is to add a device detector in your js. You can use that to display two different models on desktop and on mobile.

但您还可以带来进一步的重要改进.因为它们是我原帖的一部分,所以我让它们出现了 :) :

But there are further important improvements you can bring. As they are part of my original post I let them there :) :

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

  1. Resize your textures. You are using two 4096 x 4096 jpg of 4.5MB, this is heavy (note that there are webgl-enabled smartphones with only 500Mo RAM that get realeased these days). Moreover you have very few details that justifies it. You could change your uv to reduce a lot the parts with no details, and probably resize the picture to 512x512. Finally, use a JPG compressor that will reduce the weight by 70-80%. Depending on your picture PNG can be a better choice also. The device's GPU memory is still something else, and if you still need to improve performance you can check in the script if the client supports .pvr or .ktx texture formats, optimized for GPU memory.

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

An important problem that makes your visualization unappropriate for mobile devices is that you have ... 23 render calls, because you are using 15 textures and 23 geometries.

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

What it means is that, for each frame, you will have to bind 23 different geometries before the final frame renders. Some mobile CPU-GPU couples cannot do that 60 times per second. Don't plan more than 10 render calls for average mobile devices. That means less geometries with less materials. Merge.

我没有详细检查您的 .obj 文件以了解您最终是如何获得 23 个几何图形的,而您的 13 个纹理来自何处,由您决定.

I have not inspected your .obj file in detail to understand how you get 23 geometries in the end, neither where your 13 textures come from, up to you.

商店中的许多 3D 应用程序 (OpenGL) 当然拥有超过 23 个对象.但商店知道应用程序,他们知道您的手机,因此他们可以执行兼容性工作并将应用程序隐藏到低设备.

A lot of 3D apps (OpenGL) on the stores have more than 23 objects of course. But stores know the apps and they know your phone so they can do the compatibility job and hide the app to low devices.

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

Here is the tip to check your render calls, geometries and materials in the scene : in your main function, after having set the renderer, include a pointer to it in the window object window.renderer = renderer. Now at runtime in your console, once resources have been loaded, type renderer.info. It will return those data in an object.

这篇关于Three.js 项目导致手机崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 07:40