ソースからパーティクルを生成し、その位置を更新するシステムがあります。現在、OpenGL で my GenerateParticles(...)
andを呼び出しUpdateParticles(...)
て出力を表示するプログラムを作成しています。私のシステムに持たせたい機能の 1 つは、n
1 秒ごとにパーティクルを生成できることです。GenerateParticles(...)
関数と関数では、 2 つの重要なパラメーターとUpdateParticles(...)
を受け入れます。では、次の式に従ってパーティクルの位置を更新します。これらのパラメーターとグローバル変数 (またはその他のメカニズム) を使用して、 1 秒あたりのパーティクルを生成するにはどうすればよいですか?current_time
delta_time
UpdateParticles(...)
new_pos = curr_pos + delta_time*particle_vector
n
3 に答える
注意が必要です。パーティクルを作成する素朴な方法では、 の値が低い場合に分数パーティクルを作成することになります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;
}
}
タイム デルタが大きい場合に一度に 100 万個のパーティクルを作成しないように、何らかの制限を加えてください。
フレームで放出されるパーティクルの数は、次のように計算できます。
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 つの利点は、パーティクル システムが不均一に見えることです。たとえば、周波数が 1.5 でデルタ時間が 1 の場合、最初のアプローチを使用すると、フレームは 1、2、1、2、... パーティクルのシーケンスを放出します。2 番目のアプローチは、このパターンを破ることができます。
また、 を使用しmodf()
て浮動小数点数の整数部分と小数部分を抽出することもできます。
n * delta_time
でパーティクルを作成するだけですGenerateParticles
。