2015-11-26 1 views
0

Voici la fonction de mise à jour. Dès que je tourne la mise à jour sur mon programme devient plus lent. Je ne suis même pas capable de rendre 25000 particules à la fois. Voxels est un tableau en trois dimensions. Comment modifier ma fonction de mise à jour pour que les calculs soient effectués plus rapidement. je veux pouvoir rendre au moins 100000 particules.Système de particules fonctionnant lentement

function update(){ 

newTime = Date.now(); 
elapsedTime = newTime - oldTime; 
oldTime = newTime; 


for(var index =0 ; index < particles.vertices.length; index++){ 

    //particle's old position 
    var oldPosition = particles.vertices[index]; 

    //making sure particles do not og out of boundary 
    if (oldPosition.x > screenSquareLength || oldPosition.x < -screenSquareLength){ 
     oldPosition.x = 2 * screenSquareLength * Math.random() - screenSquareLength; 
    } 
    if (oldPosition.y > screenSquareLength || oldPosition.y < -screenSquareLength){ 
     oldPosition.y = 2 * screenSquareLength * Math.random() - screenSquareLength; 
    } 
    if (oldPosition.z > screenSquareDepth/2 || oldPosition.z < -screenSquareDepth/2){ 
     oldPosition.z = screenSquareDepth * Math.random() - screenSquareDepth/2; 
    } 


    var oldVelocity = particlesExtraInfo[index].velocity; 
    var fieldVelocity; 
    var xIndex, yIndex, zIndex; 


    try{ 
     //calculating index of voxel 
     xIndex = Math.floor((oldPosition.x + screenSquareLength)/voxelSize); 
     yIndex = Math.floor((oldPosition.y + screenSquareLength)/voxelSize); 
     zIndex = Math.floor((screenSquareDepth/2 - oldPosition.z)/voxelSize); 


     //getting velocity, color for particle and if voxel is 
     fieldVelocity = voxels[zIndex][xIndex][yIndex].userData["velocity"]; 
     particleColor = voxels[zIndex][xIndex][yIndex].userData["color"]; 
     activeVoxel = voxels[zIndex][xIndex][yIndex].userData["visible"]; 

    }catch (e){ 
     console.log("indexX = "+xIndex + " \t Yindex = "+ yIndex+" \t zIndex = "+ zIndex); 
    } 


    var particleColor; 
    var activeVoxel; 



    try{ 

     var vx = ((oldVelocity.x + fieldVelocity.x) * elapsedTime); 
     var vy = ((oldVelocity.y + fieldVelocity.y) * elapsedTime); 
     var vz = ((oldVelocity.z + fieldVelocity.z) * elapsedTime); 
     var magnitude = Math.abs(vx) + Math.abs(vy) + Math.abs(vz); //Math.sqrt(vx*vx + vy*vy+ vz*vz); 
     var normalized = new THREE.Vector3(vx/magnitude, vy/magnitude, vz/magnitude); 



     if((particles.vertices[index].x < 0.1 && particles.vertices[index].x > -0.1) && (particles.vertices[index].y < 0.1 && particles.vertices[index].y > -0.1) && (particles.vertices[index].z < 0.1 && particles.vertices[index].z > -0.1)){ 
      particles.vertices[index].x = 2 * screenSquareLength * Math.random() - screenSquareLength;; 
      particles.vertices[index].y = 2 * screenSquareLength * Math.random() - screenSquareLength;; 
      particles.vertices[index].z = 2 * screenSquareLength * Math.random() - screenSquareLength;; 
     } 



     //if voxel is not part of the model update particle postion and velocity 
     if(activeVoxel == 0){ 
      particles.colors[index] = new THREE.Color(particleColor);//new THREE.Color(0, 0, 1); 
      particles.colorsNeedUpdate = true; 

      particles.vertices[index].x += normalized.x/slowingFactor; 
      particles.vertices[index].y += normalized.y/slowingFactor; 
      particles.vertices[index].z += normalized.z/slowingFactor; 
      particles.verticesNeedUpdate = true; 
      particlesExtraInfo[index].velocity = normalized; 
     }else{ 
      //voxel is part of particle so update color property of particle 
      particles.colors[index] = new THREE.Color(0, 0, 1); 
      particles.colorsNeedUpdate = true; 



      particles.vertices[index].x += normalized.x/(slowingFactor * 200); 
      particles.vertices[index].y += normalized.y/(slowingFactor * 200); 
      particles.vertices[index].z += normalized.z/(slowingFactor * 200); 

      particles.verticesNeedUpdate = true; 

      particlesExtraInfo[index].velocity = new THREE.Vector3(normalized.x/slowingFactor, normalized.y/slowingFactor, normalized.z/slowingFactor); 

     } 
    }catch(e){ 

    } 
} 

}

Répondre

0

Je ne sais pas grand chose sur ce qui se passe exactement comme lorsque vous mettez à jour un tampon, mais je sais qu'il peut être lent. Alors que 25k peut être beaucoup pour ce que vous essayez de faire (j'ai expérimenté avec 5k et ai eu des problèmes) il n'y a aucune raison pour laquelle vous ne pouvez pas optimiser votre JS avant d'essayer de tout déplacer vers le GPU (par exemple).

var foo = 0; 

foo+= normalized.x/someFactor; 

//better done this way: 
var invSomeFactor = 1/someFactor; 

// now you avoid dividing the same thing many times in your loop 
foo += normalized.x * invSomeFactor; 

Math.random() est assez cher, vous pourriez faire une table (une grande) et allez chercher ces valeurs précalculées de lui.

var myLookupTable = []; 
var MAX_VALUES = 2048; 

for (var i = 0 ; i < MAX_VALUES ; i ++){ 
    myLookupTable.push(Math.random()); 
} 

//and then you can have a stride for example 
var RAND_STRIDE = 0; 

//and in the loop 
    someVec.x += something.x * myLookupTable[ RAND_STRIDE ++ ]; 

    RAND_STRIDE %= MAX_VALUES; //read from the beginning 

Enfin, vous pouvez écrire un fragment shader, qui se lirait d'un tampon, et d'écrire dans un autre tampon faisant tout cette logique dans le processus. Chaque fragment est votre particule et une fois que vous exécutez ce passage et calculez vos positions, vous devez être capable de lire le tampon dans votre vertex shader de particules et d'attribuer ces positions.