用粒子控制数千条鱼

问题在于 MeshInstances 更新他们的变换数组是很昂贵的。它非常适合在场景周围放置许多静态对象。但在现场周围移动物体仍然很困难。

为了使每个实例以有趣的方式移动,我们将使用 Particles 节点。粒子通过计算和设置 Shader .

注解

粒子在gles2中不可用,请使用 CPUParticles 这与粒子的作用相同,但不能从GPU加速中获益。

首先创建粒子节点。然后,在“绘制过程”下,将粒子的“绘制过程1”设置为 Mesh . 然后在“工艺材料”下创建一个新的 ShaderMaterial .

设置 shader_typeparticles .

shader_type particles

然后添加以下两个函数:

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 .

关于粒子遮影器的一个独特之处是一些内置变量跨帧保存。 TRANSFORMCOLORCUSTOM 可以在网格的空间明暗器和下次运行时的粒子明暗器中访问所有这些。

接下来,设置您的 vertex 功能。粒子明暗器仅包含顶点函数,不包含其他函数。

首先,我们将区分只在粒子系统启动时需要运行的代码和应该始终运行的代码。当系统首次运行时,我们想给每条鱼一个随机的位置和一个随机的动画偏移量,所以我们将代码包装在 if 检查内置变量的语句 RESTART 当粒子系统重新启动时,对于一个帧,该值变为真。

从高层来看,这看起来是:

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

接下来,我们需要生成4个随机数:3个用于创建随机位置,1个用于游泳周期的随机偏移。

首先,在 RESTART 阻止使用 hash 上述功能:

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);

然后,使用这些种子生成随机数 rand_from_seed

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);

最后,分配 positionTRANSFORM[3].xyz ,它是保存位置信息的转换的一部分。

TRANSFORM[3].xyz = position * 20.0;

记住,所有这些代码都在 RESTART 块。

网格的顶点明暗器可以保持与上一教程中的完全相同。

现在,您可以将每个鱼单独移动到每个帧,或者添加到 TRANSFORM 直接或通过写信给 VELOCITY .

让我们通过设置它们的 VELOCITY .

VELOCITY.z = 10.0;

这是最基本的设置方法 VELOCITY 每个粒子(或鱼)都有相同的速度。

只是通过设置 VELOCITY 你可以让鱼随意游动。例如,尝试下面的代码。

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

这将使每条鱼在 210 .

如果你用过 CUSTOM.y 在上一个教程中,还可以基于 VELOCITY . 只是使用 CUSTOM.y .

CUSTOM.y = VELOCITY.z * 0.1;

此代码提供以下行为:

../../../_images/scene.gif

使用颗粒材料可以使鱼的行为变得简单或复杂。在本教程中,我们只设置速度,但在您自己的明暗器中,也可以设置 COLOR ,旋转,缩放(通过 TRANSFORM )请参阅 Particles Shader Reference 有关粒子着色器的详细信息。