粒子系统: 粒子生成

4
我有一个系统可以从源生成粒子并更新它们的位置。目前,我已经在OpenGL中编写了一个程序,调用我的GenerateParticles(...)UpdateParticles(...)函数,并显示输出结果。我希望我的系统具备的一项功能是每秒能够生成n个粒子。在我的GenerateParticles(...)UpdateParticles(...)函数中,我接受两个重要参数:current_timedelta_time。在UpdateParticles(...)函数中,我根据以下公式更新粒子的位置:new_pos = curr_pos + delta_time*particle_vector。我如何使用这些参数和全局变量(或其他机制)来每秒产生n个粒子?
3个回答

2

你需要小心,简单创建粒子的方式会让你在n值较低时创建分数粒子(可能不是你想要的)。相反,创建一个累加器变量,每帧将其与delta_time值相加。每帧检查它,以确定该帧需要创建多少个粒子,并减去适当的数量:

void GenerateParticles(double delta_time) {
  accumulator += delta_time;
  while (accumulator > 1.0 / particles_per_second) {
    CreateParticle(...);
    accumulator -= 1.0 / particles_per_second;
  }  
}

请确保添加一些限制,以防时间差很大时同时创建大量的粒子。


1

一个帧发射的粒子数量可以通过以下方式计算:

double n = delta_time * frequency
int i = (int)n;
f = n - i;

基本上,您可以发射 i 粒子。

小数部分f可以累积到以后的帧中。当它累积大于1时,您可以发射整数个粒子:

f_sum += f;
if (f_sum > 1.0) {
    int j = (int)f_sum;
    f_sum -= j;
    i += j;
}

然而,以下是另一种有趣的解决方案,适用于粒子的分数数量。通过使用伪随机数生成器(PRNG),我们可以使用它来确定是否应该发射粒子:
if (f >= r()) // Assumes r() is a PRNG generating a random value in [0, 1) 
    i++;

当频率随时间变化时,这种方法非常有用。它消除了存储额外变量的需要。

此方法的另一个优点是,粒子系统看起来不那么均匀。例如,如果频率为1.5,时间差为1,则使用第一种方法,帧将发出1、2、1、2等粒子序列。第二种方法可以打破这个模式。

此外,您可以使用modf()来提取浮点数的整数和小数部分。


0

你只需要在 GenerateParticles 函数中创建 n * delta_time 个粒子。


delta_time通常是小于零的双精度浮点数。假设我不能创建一个粒子的一部分。 - Myx
@Myx:我想你的意思是小于1吧?正如@Ron指出的那样,这并不是问题,尽管累加n * delta_time并将其与1.进行比较更简单、更快... - Troubadour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接