我正在使用ShaderParticleEngine库为Three.js创建粒子发射器。
我在互联网上选择了几个代码片段,以便有一个可工作的发射器。首先,我认为这是行不通的。
但是事实上,发射器显示在地图上,但是屏幕上有一个静止的粒子。经过一些调试后,我发现粒子在移动,但速度是无限缓慢的。我需要使用tick(delta * 1000)来查看发射器的作用。结果是相当丑陋的(充满空隙,单独粒子)。我没有问题的低FPS。
我找到的唯一解决方案是删除particleGroup.tick()函数调用中的增量参数。
结果更好,但仍然是骗人的,由你自己来判断:
在线发射器编辑器:

我的结果:

我不明白。我使用库示例中提出的相同代码,在发射器编辑器中使用导出特性。如果我尝试其他变体(如。关于粒子的寿命/速度)我在我的游戏中得到了一个非常不同的结果,也许粒子寿命没有被正确地计算,因为δ参数没有给出?
我的游戏回路:
var animate = function () {
requestAnimationFrame( animate );
render();
stats.update();
};
var render = function() {
time = ctx3d.clock.getElapsedTime();
delta = ctx3d.clock.getDelta();
particleGroup.tick(delta);
if(ctx3d.move)
{
ctx3d.ship.position.z += delta * 500 * 3000;
//ctx3d.camera.position.x = ctx3d.ship.position.x;
//ctx3d.camera.position.z = ctx3d.ship.position.z;
}
ctx3d.renderer.render(ctx3d.scene, ctx3d.camera);
}增量值循环:
30.000003385357559 9.99851953523e-7 30.000002000000006770715117 0.000003385357559 30.000003385357559 30.00000200006770715117 0.000003385357559 0.000003385357559 0.0000000000006770715117 0.00000 30.000003385357559 30.000003385357559 2000000006770715117 0.00000 30.000003385357559 30.0000033000006770715117 0.0000030.000003385357559 30.0000020000006770715117 0.0000010003385357559 30.0000006770715117 0.000001003385357559 9.9957559 9.99999657559 9.995357559 9.995357559 9.995357559
发布于 2014-11-04 00:04:53
我希望把这个作为答案发布是可以的.
我已经把粒子引擎的小版本提高到了0.7.7,为你的“看起来不太流畅”的发射器实现了一个修正。
之前发生的事情是:
SPE.Emitter.tick()值调用dttick函数根据传递给它的dt参数确定应该活着标记多少粒子。对于较大的dt值,更多的粒子被标记为活着,而较小的值则被标记为alice。假设每帧有多个粒子被标记为alive,并且它们都起源于相同的空间位置,那么当它们被激活时,所有的粒子都在同一个位置。这就是为什么你看到了一些“集群”的发生。
现在发生的事情是:
SPE.Emitter.tick()使用dt值进行调用,就像以前一样。tick函数现在决定了应该将多少粒子标记为活动的,并且在标记它们的同时,将每个粒子的年龄设置为传入的dt值的一小部分。因此(!),假设每帧发射100个粒子,并将一个dt值0.016传递给发射器的tick函数,则将标记为活动的100个粒子中的每一个指定为(0.016 / 100) * i的年龄值,其中i是粒子索引(在本例中为0到100)。
我希望这是有意义的。您可以在这里看到更改:https://github.com/squarefeet/ShaderParticleEngine/blob/master/src/ShaderParticleEmitter.js#L240-L246
主分支已经更新。
发布于 2014-11-03 22:54:59
要解决平滑问题,请尝试以下方法:
function makeSmoothSPETick(simulator, timeDelta, maxSubstepSize){
var numSubsteps = Math.floor(timeDelta/maxSubstepSize);
var leftOverTime = timeDelta%maxSubstepSize;
while(numSubsteps-->0){
simulator.tick(maxSubstepSize);
}
if(leftOverTime> 0){
//handle the rest
simulator.tick(leftOverTime);
}
}如果您在代码中使用此函数--它将允许您从本质上将太大的步骤细分为较小的固定大小的步骤。正如SquareFeet所指出的,假设60 for使用16 As -您可以使用这样的方法:
var render = function() {
time = ctx3d.clock.getElapsedTime();
delta = ctx3d.clock.getDelta();
makeSmoothSPETick(particleGroup, delta, 0.016);
if(ctx3d.move)
{
ctx3d.ship.position.z += delta * 500 * 3000;
//ctx3d.camera.position.x = ctx3d.ship.position.x;
//ctx3d.camera.position.z = ctx3d.ship.position.z;
}
ctx3d.renderer.render(ctx3d.scene, ctx3d.camera);
}您应该获得与您预期的结果相似的结果,如果您是在平滑的60 get运行。但是要小心,如果目标硬件不能处理这些子步骤--您可能需要在求解器算法中获得更多的逻辑。我建议保留过去100帧左右的统计数据,并使用它来决定您可以将传入步骤值拆分多少。
编辑:为了确保您的时间不被破坏,请尝试以下操作:
var lastFrameTime = Date.now()/1000;
var animate = function () {
requestAnimationFrame( animate );
render();
stats.update();
};
var render = function() {
time = Date.now()/1000; //getting current time in seconds since epoch
delta = time-lastFrameTime;
lastFrameTime = time;
particleGroup.tick(delta);
if(ctx3d.move)
{
ctx3d.ship.position.z += delta * 500 * 3000;
//ctx3d.camera.position.x = ctx3d.ship.position.x;
//ctx3d.camera.position.z = ctx3d.ship.position.z;
}
ctx3d.renderer.render(ctx3d.scene, ctx3d.camera);
}https://stackoverflow.com/questions/26723575
复制相似问题