Work in progress

The content of this page was not yet updated for Godot 4.6 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

Управление тысячами рыб с помощью Particles (частиц)

Проблема с MeshInstance3D заключается в том, что обновление массива преобразований требует больших затрат. Этот метод отлично подходит для размещения множества статических объектов на сцене. Однако перемещать объекты по сцене всё ещё сложно.

Чтобы каждый экземпляр двигался интересным образом, мы будем использовать узел GPUParticles3D. Частицы используют ускорение GPU, вычисляя и устанавливая информацию для каждого экземпляра в узле Shader.

Сначала создайте узел Particles. Затем в разделе "Draw Passes" установите для параметра "Draw Pass 1" вашей частицы значение Mesh. Затем в разделе "Process Material" создайте новый ShaderMaterial.

Установите shader_type на particles.

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

Эти функции берутся из стандартного ParticleProcessMaterial. Они используются для генерации случайного числа на основе RANDOM_SEED каждой частицы.

Уникальной особенностью шейдеров частиц является то, что некоторые встроенные переменные сохраняются между кадрами. К TRANSFORM, COLOR и CUSTOM можно получить доступ в шейдере сетки, а также в шейдере частиц при его следующем запуске.

Затем настройте функцию start(). Шейдеры частиц содержат функции start() и process().

Код в функции start() запускается только при запуске системы частиц. Код в функции process() будет выполняться всегда.

Нам необходимо сгенерировать 4 случайных числа: 3 для создания случайного положения и одно для случайного смещения цикла плавания.

Сначала сгенерируйте 4 начальных числа внутри функции start(), используя функцию 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);

Наконец, назначьте position для TRANSFORM[3].xyz, что является частью преобразования, содержащей информацию о положении.

TRANSFORM[3].xyz = position * 20.0;

Помните, весь этот код находится внутри функции start().

Вершинный шейдер для вашей сетки может остаться точно таким же, как в предыдущем уроке.

Теперь вы можете перемещать каждую рыбу индивидуально в каждом кадре, либо напрямую добавляя TRANSFORM, либо записывая в VELOCITY.

Давайте преобразуем рыбу, установив ее VELOCITY в функции start().

VELOCITY.z = 10.0;

Это самый простой способ задать VELOCITY: каждая частица (или рыба) будет иметь одинаковую скорость.

Просто установив VELOCITY, вы можете заставить рыбу плавать так, как вам хочется. Например, попробуйте код ниже.

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

Это даст каждой рыбе уникальную скорость от 2 до 10.

Вы также можете позволить каждой рыбе менять свою скорость с течением времени, если зададите скорость в функции process().

Если в предыдущем уроке вы использовали CUSTOM.y, вы также можете задать скорость анимации плавания на основе VELOCITY. Просто используйте CUSTOM.y.

CUSTOM.y = VELOCITY.z * 0.1;

Этот код дает следующее поведение:

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

Используя ParticleProcessMaterial, вы можете сделать поведение рыбы настолько простым или сложным, насколько вам нужно. В этом уроке мы задаём только скорость, но в ваших собственных шейдерах вы также можете задать COLOR, вращение и масштаб (через TRANSFORM). Подробнее о шейдерах частиц см. в Particles Shader Reference.