风场可视化(随机重置)
引子
在绘制轨迹的效果中,过一段时间就会发现,最后只剩下固定的几条轨迹,原文中也提到了这种现象,也提供了解决思路,个人还是想结合源码再看看。
- 源库: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 generator
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));
}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 RGBAvec2 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 place
this.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
推荐阅读
- R语言数据可视化|数据可视化——R语言ggplot2包绘制箱线图叠加散点图
- 数据可视化神器,深入解读Smartbi自助仪表盘
- Spring Boot + Prometheus + Grafana 打造可视化监控,一目了然!
- 新品发布会|数据可视化编辑平台上线,小程序也能拥有可视化图层
- Java中的随机数Random
- 数据分析|数据分析学习1——数据获取,单因子探索分析与可视化
- 推荐算法+可视化|推荐算法+可视化 vue+flask 爬虫大数据项目架构思路分享
- 从数据集中随机抽取一定数量的数据
- vue+echarts可视化大屏|vue+echarts可视化大屏,全国地图下钻,页面自适应
- 当.Net撞上BI可视化,这3种“套路”你必须知道