When there’s no possibility to pass in the computations into the GPU the best way to gain some performance is by using multi-threading on the client side. Even if we’re using just one Worker we separate the UI thread from the execution thread making calculations in a much simple execution context and in most cases we can do faster calculations. The workers script has utility methods for dealing with web workers and coordinate groups of web workers with the map-reduce paradigm.
Coordinates groups of web workers.
Creates a group of web workers out of the same script.
var workerGroup = new PhiloGL.WorkerGroup(scriptName, n);
Create a group of workers to divide as an octree the space of marching cubes calculations. More information about that can be found here.
//initialize workers
var workerGroup = new WorkerGroup('WorkerMarchingCube.js', nWorkers);
Map different configuration objects into each worker. Just like using map
as an Array
method.
workerGroup.map(callback);
Divide the calculation space into an octree providing each worker with the grid dimensions of an philogl. The entire application can be seen here.
workerGroup.map(function(nb) {
var idx = nb % den,
idy = ((nb / den) >> 0) % den,
idz = ((nb / den / den) >> 0) % den;
var o = {
grid: {
x: {
from: xfrom + idx * nx,
to: xfrom + idx * nx + nx,
step: xstep
},
y: {
from: yfrom + idy * ny,
to: yfrom + idy * ny + ny,
step: ystep
},
z: {
from: zfrom + idz * nz,
to: zfrom + idz * nz + nz,
step: zstep
}
},
isolevel: 10,
balls: balls.ballsArray
};
return o;
});
Collect all the information each worker responded and merge it into a new object/value.
workerGroup.reduce(options);
Reduce all calculations from each philogl into a single object. More information here.
var indexAcum = 0, initialValue = {
vertices: [],
normals: [],
indices: []
};
workerGroup.reduce({
reduceFn: function (x, y) {
var l = y.vertices.length /3;
x.vertices = x.vertices.concat(y.vertices);
x.normals = x.normals.concat(y.normals);
while (l--) {
x.indices.push(indexAcum++);
}
return x;
},
initialValue: initialValue,
onComplete: complete
});