三个js PERFORMANCE如何更快地使用图像纹理

时间:2016-03-17 14:01:26

标签: javascript performance three.js

我有代码。抱歉,我没有要上传的图片。 在代码中我有两个功能 UseMeshNormalMaterial()UsePngMaterial() 这样您就可以轻松测试代码,如果您有一些图像。 (取消注释一个或另一个并加载页面) 两个调用之间的差异是UseMeshNormalMaterial使用MeshNormalMaterialUsePngMaterial使用MeshBasicMaterial的索引数组。差异令人吃惊。 UseMeshNormalMaterial以60fp自由运行,UsePngMaterial以0至2 fps运行。

所以我需要帮助或指导。我会在这一点上提出任何想法。

这是代码。

<!DOCTYPE html>
<html>
<head>
 <meta charset=utf-8>
 <meta name="viewport" content="width=device-width, minimum-scale=1.0">
 <title>TestHTML</title>
 <style>
  body {
   background: #fff;
   padding: 0;
   margin: 0;
   font-weight: bold;
   overflow: hidden;
  }
 </style>


</head>

<body style="margin: 0;">



 <script src="js/three.min.js"></script>
 <script src="js/stats.min.js"></script>



 <script>

        var camera = new THREE.PerspectiveCamera( 30, window.innerWidth/window.innerHeight, 0.1, 5000.0);
        var mouseX = 0, mouseY = 0;

        var aspectratio = window.innerWidth/window.innerHeight;
        var renderer = new THREE.WebGLRenderer();

        renderer.setSize(window.innerWidth, window.innerHeight);
                 renderer.shadowMap.cullFace = THREE.CullFaceFrontBack;
        renderer.gammaInput = true;
        renderer.gammaOutput = true;

        renderer.shadowMap.enabled = false;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;

        document.body.appendChild( renderer.domElement );

        var scene = new THREE.Scene();
        scene.add(camera);

        document.addEventListener( 'mousemove', onDocumentMouseMove, false );

        window.addEventListener('resize', resize, false);

        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;


        // Our Javascript will go here.
        stats = new Stats();
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.top = '0px';
        stats.domElement.style.zIndex = 100;
        document.body.appendChild( stats.domElement );


        // this  must be defined before MJMotion.js
        // we use it in there.
        var scenesizereduction = 100.0;

        var directionalLight = new THREE.DirectionalLight(0xffffff, 0.15);

        directionalLight.position.set(-100, 1000,2000);
        scene.add(directionalLight);



         var hemiLight = new THREE.HemisphereLight(0xAAAAAA, 0x080808, 0.25);
         hemiLight.position.set(0, 500, 0);
         scene.add(hemiLight);


         var  dirLight = new THREE.DirectionalLight( 0xffffff, 0 );
                     dirLight.color.setHSL( 0.1, 1, 0.95 );
                     dirLight.position.set( -1, 1.75, 1 );
                     dirLight.position.multiplyScalar( 50 );
                     scene.add( dirLight );

                     dirLight.castShadow = false;

                     dirLight.shadowMapWidth = 2048;
                     dirLight.shadowMapHeight = 2048;

                     var d = 150;

                     dirLight.shadowCameraLeft = -d;
                     dirLight.shadowCameraRight = d;
                     dirLight.shadowCameraTop = d;
                     dirLight.shadowCameraBottom = -d;

                     dirLight.shadowCameraFar = 3500;
                     dirLight.shadowBias = -0.00005;





    var textures20Geometry = new THREE.BoxGeometry(2.0,0.95 , .80 );
    var textures40Geometry = new THREE.BoxGeometry(4.0 , 0.95, .80 );
    var Cube20Mesh= new THREE.Mesh( textures20Geometry);
    var Cube40Mesh= new THREE.Mesh(textures40Geometry);
    var CubeGeometry = new THREE.Geometry();

    //Add grid
    var gridXZ = new THREE.GridHelper(1000, 100);
    gridXZ.setColors( new THREE.Color(0x8f8f8f), new THREE.Color(0x8f8f8f) );
    gridXZ.position.set(0,0,0 );
    scene.add(gridXZ);



    var CubeMaterials = [
      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube01.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube02.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube03.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube04.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube05.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube06.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube07.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube08.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube09.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube10.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube11.png')}),

      new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture('textures/cube12.png')})
    ];



 var objects = [];
 var material = new THREE.MeshNormalMaterial();

 // here are the two lines of code that make all the difference.
 //use one of the other.
 // VERY fast using NO image textures.
 UseMeshNormalMaterial();

 // VERY slow using image textures.
// UsePngMaterial();

 animate();



function UseMeshNormalMaterial()
{

 for(var i = 0; i < 25000; i++)
  {
   addCube20("cube" + i, (Math.random() * 500) - 50, (Math.random() * 500) - 50, Math.random() * 2 * Math.PI,1);

   addCube40("cube" + i, (Math.random() * 500) - 50, (Math.random() * 500) - 50, Math.random() * 2 * Math.PI,6);
  }

 DisplayCubes();
}

function UsePngMaterial()
{

 for(var i = 0; i < 25000; i++)
  {
   addCube201("cube" + i, (Math.random() * 500) - 50, (Math.random() * 500) - 50, Math.random() * 2 * Math.PI,1);

   addCube401("cube" + i, (Math.random() * 500) - 50, (Math.random() * 500) - 50, Math.random() * 2 * Math.PI,6);
  }

 DisplayCubes1();

}


function addCube20(name, x1,z1,azimuth,MaterialIndex)
 {
  Cube20Mesh.position.set(x1, (Math.random() * 100) - 100, z1);
  Cube20Mesh.rotation.x =  azimuth;
  Cube20Mesh.rotation.y =  Math.random() * 2 * Math.PI;
  Cube20Mesh.name = name;
  Cube20Mesh.updateMatrix();
  CubeGeometry.merge(Cube20Mesh.geometry, Cube20Mesh.matrix);
 };


function addCube40(name, x1,z1,azimuth,MaterialIndex)
{
 Cube40Mesh.position.set(x1, (Math.random() * 100) - 100, z1);
 Cube40Mesh.rotation.x = azimuth;
 Cube40Mesh.rotation.y = Math.random() * 2 * Math.PI;
 Cube40Mesh.name = name;
 Cube40Mesh.updateMatrix();
 CubeGeometry.merge(Cube40Mesh.geometry, Cube40Mesh.matrix);
 };


 function addCube201(name, x1,z1,azimuth,MaterialIndex)
  {
   Cube20Mesh.position.set(x1, (Math.random() * 100) - 100, z1);
   Cube20Mesh.rotation.x =  azimuth;
   Cube20Mesh.rotation.y =  Math.random() * 2 * Math.PI;
   Cube20Mesh.name = name;
   Cube20Mesh.updateMatrix();
   CubeGeometry.merge(Cube20Mesh.geometry, Cube20Mesh.matrix,MaterialIndex);
  };


 function addCube401(name, x1,z1,azimuth,MaterialIndex)
  {
   Cube40Mesh.position.set(x1, (Math.random() * 100) - 100, z1);
   Cube40Mesh.rotation.x = azimuth;
   Cube40Mesh.rotation.y = Math.random() * 2 * Math.PI;
   Cube40Mesh.name = name;
   Cube40Mesh.updateMatrix();
   CubeGeometry.merge(Cube40Mesh.geometry, Cube40Mesh.matrix,MaterialIndex);
  };



function DisplayCubes()
 {
   var CubeGroup = new THREE.Mesh(CubeGeometry,  material);
   CubeGroup.matrixAutoUpdate = false;
   CubeGroup.updateMatrix();
   scene.add(CubeGroup);
 };

function DisplayCubes1()
 {
  var CubeGroup = new THREE.Mesh(CubeGeometry, new THREE.MeshFaceMaterial(CubeMaterials));
  CubeGroup.matrixAutoUpdate = false;
  CubeGroup.updateMatrix();
  scene.add(CubeGroup);
 };


 function onDocumentMouseMove(event)
  {
   mouseX = ( event.clientX - windowHalfX ) * 10;
   mouseY = ( event.clientY - windowHalfY ) * 10;
  };


 function resize()
  {
   windowHalfX = window.innerWidth / 2;
   windowHalfY = window.innerHeight / 2;
   renderer.setSize(window.innerWidth, window.innerHeight);
   camera.aspect = window.innerWidth / window.innerHeight;
   camera.updateProjectionMatrix();
  };


  function animate()
   {
    camera.position.x += ( mouseX - camera.position.x ) * .005;
    camera.position.y += ( - mouseY - camera.position.y ) * .005;
    camera.lookAt( scene.position );
    for ( var i = 0, il = objects.length; i < il; i ++ )
     {
      objects[ i ].rotation.x += 0.01;
      objects[ i ].rotation.y += 0.02;
     }

    requestAnimationFrame( animate );
    renderer.render(scene, camera);
    stats.update();
   };




 </script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

CubeGeometry.sortFacesByMaterialIndex()是神奇的子弹。 如果没有这个调用并使用三个js将会进行数千次调用,但是如果你对sortFacesByMaterialIndex进行排序,它会分解为几个。