用粒子控制数千条鱼

MeshInstance 的问题是,更新转换数组的代价很高。它非常适合在场景周围放置许多静态对象。但在场景中移动物体仍然很困难。 Particles 节点.Particles通过在 Shader 中计算和设置每个实例的信息来利用GPU加速. 注解 CPUParticle,它和 Partile 的功能相同,但是不能使用 GPU 加速。 Mesh . 然后在 “Process Material “下创建一个新的 ShaderMaterial . 将 “着色器_类型” 设置为 “粒子”.

  1. shader_type particles

然后添加以下两个函数:

  1. float rand_from_seed(in uint seed) { int k; int s = int(seed); if (s == 0) s = 305420679; k = s / 127773; s = 16807 * (s - k * 127773) - 2836 * k; if (s < 0) s += 2147483647; seed = uint(s); return float(seed % uint(65536)) / 65535.0;}uint hash(uint x) { x = ((x >> uint(16)) ^ x) * uint(73244475); x = ((x >> uint(16)) ^ x) * uint(73244475); x = (x >> uint(16)) ^ x; return x;}

ParticlesMaterial ,可以用来根据每个粒子的 RANDOM_SEED 生成随机数。 TRANSFORM , COLORCUSTOM 都可以在网格的Spatial shader 中访问, 下次运行时也可以在粒子着色器中访问. 接下来, 设置您的 “顶点” 函数. 粒子着色器只包含一个顶点函数, 不包含其他函数. if 语句中, 检查内置变量 RESTART , 当粒子系统重新启动时, 该变量在第一帧变成 true . 从高的级别来看, 这看起来像:

  1. void vertex() { if (RESTART) { //Initialization code goes here } else { //per-frame code goes here }}

接下来, 我们需要生成4个随机数:3个用于创建一个随机位置,1个用于游泳周期的随机偏移量. 首先, 使用上面提供的 “哈希” 函数在 “重新开始” 块中生成4个种子:

  1. uint alt_seed1 = hash(NUMBER + uint(1) + RANDOM_SEED);uint alt_seed2 = hash(NUMBER + uint(27) + RANDOM_SEED);uint alt_seed3 = hash(NUMBER + uint(43) + RANDOM_SEED);uint alt_seed4 = hash(NUMBER + uint(111) + RANDOM_SEED);

然后, 使用这些种子生成随机数, 使用 “随机种子”:

  1. CUSTOM.x = rand_from_seed(alt_seed1);vec3 position = vec3(rand_from_seed(alt_seed2) * 2.0 - 1.0, rand_from_seed(alt_seed3) * 2.0 - 1.0, rand_from_seed(alt_seed4) * 2.0 - 1.0);

最后, 将 “位置” 赋值给 “TRANSFORM[3].xyz”, 它是保存位置信息的转换的一部分.

  1. TRANSFORM[3].xyz = position * 20.0;

记住, 到目前为止, 所有这些代码都位于 “重新开始” 块中. 网格的顶点着色器, 可以完全复用前一教程中的. 现在你可以单独移动每条鱼的每一帧, 可以通过直接增加 “变换 “, 或是通过编写” 速度”. 让我们通过设置鱼的 “速度” 来改变它们.

  1. VELOCITY.z = 10.0;

这是设置 “速度” 的最基本方法, 每个粒子(或鱼)都有相同的速度. 只要设置 “速度”, 你就可以让鱼自由游动. 例如, 尝试下面的代码.

  1. VELOCITY.z = cos(TIME + CUSTOM.x * 6.28) * 4.0 + 6.0;

这将给每条鱼一个在 “2” 和 “10” 之间的独特速度. 如果你在上节课中使用 “自定义.y “, 你也可以只使用” 自定义.y “, 根据” 速度”设置游泳动画的速度.

  1. CUSTOM.y = VELOCITY.z * 0.1;

代码产生的效果如图: COLOR、旋转、缩放(通过 TRANSFORM)。有关粒子着色器的更多信息,请参阅粒子着色器参考手册。