这里是更新功能。一旦我更新我的程序变慢。我甚至无法一次渲染25000个粒子。体素是三维阵列。如何更改我的更新功能,以便更快地完成计算。我希望能够渲染至少100000个粒子。
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){
}
}
}
答案 0 :(得分:0)
我不太了解更新这样的缓冲区时会发生什么,但我知道它可能很慢。
虽然25k可能对你正在尝试做的事情很重要(我用5k试验并遇到麻烦)但是没有理由为什么你不能在尝试将所有内容移到gpu之前优化你的JS (例如)。
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()非常昂贵,您可以创建一个查找表(一个大表)并从中获取这些预先计算的值。
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
最后,您可以编写一个片段着色器,它将从缓冲区读取,并写入另一个缓冲区,在该过程中执行所有这些逻辑。每个片段都是你的粒子,一旦你运行这个传递并计算你的位置,你需要能够在粒子顶点着色器中读取缓冲区并只分配这些位置。