three.js中的帧率下降/效率问题

时间:2018-12-06 13:56:14

标签: graphics three.js 3d webgl

运行时,fps会缓慢但持续下降。我试图确定负责任的职能,看来是这样的:

updatepoints()和rotateTriangle()似乎是罪魁祸首,但很明显,我误解了某些东西,或者使用了效率低下的方法来计算某处的东西

在使用浏览器工具进行进一步检查时,似乎是一个数组和一个对象正在填充内存,我猜这是导致帧丢失的原因。 我还注意到,浏览器工具的“性能”标签中的缓冲区正在填充

我知道bufferGeometry是创建对象的更有效方法,但我仍然想知道导致性能问题的原因

很抱歉,仅转储代码,但是我觉得这似乎很明显。

非常感谢您发现问题和解决方案的任何建议或方法。
//every scene needs these
var scene, camera, renderer, controls;

//links div with canvas
var canvas = document.getElementById('canvas');

// What I need are number of particles and the length the curve goes to be uncoupled
// Each part of degree array serves one particles
// If I added a factor so:
// factor * coord *

//creating particles
var particleCount = 360;
var particles = [];
var particles2 = [];
var particles3 = [];
var SPEED = 0.01;

var radians, y, x;
var centerX = 0;
var centerY = 0;
var radius = 231.84;
var pointPositions=[];

var vupdateXvertices, updateYvertices, updateXvertices2, updateYvertices2,
updateXvertices3, updateYvertices3;

var pivot1;
var parent;

var pointsX = [];
var pointsY = [];

var particleMaterial = new THREE.MeshBasicMaterial({
    color: 0x7a7a7a,
    transparent: true,
    opacity: 0.8
});

init();
animate();

function init() {
  scene = new THREE.Scene();
  //setup camera for scene
  //PerspectiveCamera(fov, aspect, near, far [In terms of camera frustum plane])
  camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
  camera.position.z = 1000;
  //setup renderer for scene (generation of whatever you've made)
  renderer = new THREE.WebGLRenderer();
  renderer.setClearColor(0x31AED1, 1);
  renderer.setSize( window.innerWidth, window.innerHeight );
  //OrbitControls(Camera, HTMLDOMElement)
  controls = new THREE.OrbitControls( camera, renderer.domElement );
  // Set to true to enable damping (inertia), which can be used to give a sense
  //of weight to the controls. Default is false.
  controls.enableDamping = true;
  controls.dampingFactor = 0.25;
  controls.enableZoom = false;
  console.log("Called");
  fillSceneWithParticles();
  fillSceneWithShapes();
  canvas.appendChild( renderer.domElement );
  renderer.render( scene, camera );
}


function fillSceneWithParticles() {
  var particleGeometry = new THREE.SphereGeometry(3, 32, 32);
  parent = new THREE.Object3D();
  scene.add(parent);

  for (var i = 0; i < particleCount; i++) {
     particles[i] = new THREE.Mesh( particleGeometry, particleMaterial );
     particles[i].position.x = 0;
     particles[i].position.y = 0;
     particles[i].position.z = (0);

     particles2[i] = new THREE.Mesh( particleGeometry, particleMaterial );
     particles2[i].position.x = (200);
     particles2[i].position.y = (-115.57);
     particles2[i].position.z = (0);

    particles3[i] = new THREE.Mesh( particleGeometry, particleMaterial );
    particles3[i].position.x = (0);
    particles3[i].position.y = (231.84);
    particles3[i].position.z = (0);

    scene.add(particles[i]);
    scene.add(particles2[i]);
    scene.add(particles3[i]);
  }
}

function fillSceneWithShapes() {
  //Add a 2d Triangle W centre = 200, 115.57
  var geometry = new THREE.Geometry();
  geometry.vertices.push( new THREE.Vector3(-200, -115.57, 0));
  geometry.vertices.push( new THREE.Vector3( 200, -115.57, 0 ));
  geometry.vertices.push( new THREE.Vector3( 0, 231.84, 0 ));
  geometry.vertices.push( new THREE.Vector3( -200, -115.57, 0 ));
  var material = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );
  line = new THREE.Line( geometry, material );
  scene.add(line);
}


function rotateTriangle() {
  var geom = line.geometry.clone();
  geom.applyMatrix(line.matrix);
  updateXvertices = geom.vertices[0].x;
  //The circle that we use to place our points
  var centerX = 0;
  var centerY = 0;
  var radius = 231.84;
  for(var degree = 90; degree < 450; degree++){
    var radians = degree * Math.PI/180;
    var x = centerX + radius * Math.cos(radians);
    var y = centerY + radius * Math.sin(radians);
    pointsX[degree - 90] = x;
    pointsY[degree - 90] = y;
  }
}

function updatePoints() {
    //link counter with number of degrees initially created
    //These are intialised because V1 = 120 degrees from V0 and V2 = 240 degrees
    var counter = 120;
    var counter2 = 240;
    var zCounter = 0;
    var curveFactor = 1;
    var material = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );
    var secondTriangle = new THREE.Geometry();

    for (var i = 0; i < particleCount; i++) {
      parent.add(particles[i]);
      //Plot points around the circle relative to vertices of triangle
      particles[i].position.x = (pointsX[i]);
      particles[i].position.y = (pointsY[i]);
      particles[i].position.z = zCounter * curveFactor;

      //If array index out of bounds then loop back to the start of array
      //i.e. Go back around the circle relative to the triangle vertices
      parent.add(particles2[i]);
      if (counter == 360) {
        counter = 0;
      }
      particles2[i].position.x = (pointsX[counter]);
      particles2[i].position.y = (pointsY[counter]);
      particles2[i].position.z = zCounter * curveFactor;
      counter++;

      if (counter2 == 360) {
        counter2 = 0;
      }
      parent.add(particles3[i]);
      particles3[i].position.x = (pointsX[counter2]);
      particles3[i].position.y = (pointsY[counter2]);
      particles3[i].position.z = zCounter * curveFactor;
      counter2++;
      zCounter++;
    }
      //Give the second triangle the position of the last particles in array
      secondTriangle.vertices.push( new THREE.Vector3(particles[particleCount-1].position.x, particles[particleCount-1].position.y, particles[particleCount-1].position.z ));
      secondTriangle.vertices.push( new THREE.Vector3(particles2[particleCount-1].position.x, particles2[particleCount-1].position.y, particles2[particleCount-1].position.z ));
      secondTriangle.vertices.push( new THREE.Vector3(particles3[particleCount-1].position.x, particles3[particleCount-1].position.y, particles3[particleCount-1].position.z ));
      secondTriangle.vertices.push( new THREE.Vector3(particles[particleCount-1].position.x, particles[particleCount-1].position.y, particles[particleCount-1].position.z ));
      line1 = new THREE.Line( secondTriangle, material );
      scene.add(line1);
      parent.add(line1);
}

function animate() {
    requestAnimationFrame( animate );
    controls.update();
    rotateTriangle();
    updatePoints();
    line1.rotation.z -= SPEED *2;
    line.rotation.z -= SPEED *2;
    parent.rotation.z -= SPEED *2;
    renderer.render( scene, camera );
}

1 个答案:

答案 0 :(得分:2)

回想起来,问题出在哪里。

由于我在动画循环中添加了geometry.vertices.push,因此不断将新的Vector推入缓冲区。 我只需要推动这些顶点的移动即可解决我遇到的任何帧频和内存问题