引子

在绘制轨迹的成果中,过一段时间就会发现,最初只剩下固定的几条轨迹,原文中也提到了这种景象,也提供了解决思路,集体还是想联合源码再看看。

  • 源库:webgl-wind
  • Origin
  • My GitHub

起因

随着时间推移,有些粒子产生的偏移超过了范畴就会隐没,所以须要随机重置隐没的风粒子。

解决方案

须要思考的问题有:

  • 什么时候重置?
  • 重置的判断条件是什么?
  • 重置的形式是什么?

什么时候重置?

在绘制轨迹中,咱们晓得了产生的偏移是在最初更新粒子纹理信息阶段,这个机会判断保留新的粒子状态还是重置比拟适合。

重置的判断条件是什么?

相干的次要逻辑如下:

const updateFrag = `uniform float u_rand_seed;uniform float u_drop_rate;uniform float u_drop_rate_bump;// pseudo-random generatorconst vec3 rand_constants = vec3(12.9898, 78.233, 4375.85453);float rand(const vec2 co) {    float t = dot(rand_constants.xy, co);    return fract(sin(t) * (rand_constants.z + t));}void main() {  vec4 color = texture2D(u_particles, v_tex_pos);  vec2 pos = vec2(      color.r / 255.0 + color.b,      color.g / 255.0 + color.a); // decode particle position from pixel RGBA  vec2 velocity = mix(u_wind_min, u_wind_max, lookup_wind(pos));  float speed_t = length(velocity) / length(u_wind_max);  pos = fract(1.0 + pos + offset);  // a random seed to use for the particle drop  vec2 seed = (pos + v_tex_pos) * u_rand_seed;  // drop rate is a chance a particle will restart at random position, to avoid degeneration  float drop_rate = u_drop_rate + speed_t * u_drop_rate_bump;  float drop = step(1.0 - drop_rate, rand(seed));  vec2 random_pos = vec2(      rand(seed + 1.3),      rand(seed + 2.1));  pos = mix(pos, random_pos, drop);}`this.dropRate = 0.003; // how often the particles move to a random placethis.dropRateBump = 0.01; // drop rate increase relative to individual particle speed// 代码省略gl.uniform1f(program.u_rand_seed, Math.random());gl.uniform1f(program.u_drop_rate, this.dropRate);gl.uniform1f(program.u_drop_rate_bump, this.dropRateBump);

先介绍一下内置函数:

  • step(edge, x):如果 x < edge ,则返回 0.0 ,否则返回 1.0 。
vec2 seed = (pos + v_tex_pos) * u_rand_seed;

失去的偏移后的地位 pos 加上顶点地位 v_tex_pos ,乘以随机 [0, 1) 之间的随机数 u_rand_seed ,失去一个随机粒子地位 seed

float drop_rate = u_drop_rate + speed_t * u_drop_rate_bump;

粒子插值百分比 speed_t 乘以自定义单个粒子流失率 u_drop_rate_bump ,再加上自定义整体流失率,失去综合流失率 drop_rate

float drop = step(1.0 - drop_rate, rand(seed));

如果 rand(seed) 小于综合非流失率 1.0 - drop_rate ,那么 drop = 0 ,示意不会重置粒子,否则就会重置粒子。

重置的形式是什么?

重置的形式就是下面的这部分:

const vec3 rand_constants = vec3(12.9898, 78.233, 4375.85453);float rand(const vec2 co) {    float t = dot(rand_constants.xy, co);    return fract(sin(t) * (rand_constants.z + t));}vec2 seed = (pos + v_tex_pos) * u_rand_seed;vec2 random_pos = vec2(    rand(seed + 1.3),    rand(seed + 2.1));

这个次要就是原文中所说生成伪随机数。至于为什么用这样的计算形式,须要在数学方面下功夫。

参考资料

  • How I built a wind map with WebGL