reckfellENGINE

MultiMesh: вершинная анимация множества экземпляров

Одна сетка, отдельная фаза каждого экземпляра и правильные границы отсечения.

На этой странице

Начать с полного примера

Используйте пять файлов и шаги запуска, оставив ParticleMotion=false. В этом режиме C# один раз задаёт расположение, а vertex-шейдер деформирует сетку при отрисовке.

Реальная отрисовка 2 048 экземпляров

Данные экземпляра

TransformFormat и UseCustomData задаются до InstanceCount. После выделения ненулевого количества менять формат нельзя без перераспределения. InstanceCount — ёмкость, VisibleInstanceCount — число рисуемых первых экземпляров: 0 скрывает группу, -1 разрешает всю ёмкость. Это не автоматическое отсечение каждой рыбы.

VertexSchool3D.cs
C#
using Reckfell;

public partial class VertexSchool3D : MultiMeshInstance3D
{
    public ShaderMaterial SwimMaterial { get; private set; } = null!;

    public bool TryBuild(int count)
    {
        if (count < 1 || count > 8192) return false;
        var layout = SchoolMesh.Layout(count);
        SwimMaterial = new ShaderMaterial { Shader = new Shader { Code = SchoolShaders.Swim } };
        var data = new MultiMesh
        {
            TransformFormat = MultiMesh.TransformFormatEnum.Transform3D,
            UseCustomData = true,
            Mesh = SchoolMesh.Create(),
            InstanceCount = count,
            CustomAabb = layout.Bounds
        };
        for (int i = 0; i < count; i++)
        {
            float x = (i % layout.Columns - (layout.Columns - 1) * 0.5f) * 0.85f;
            float y = (i / layout.Columns - (layout.Rows - 1) * 0.5f) * 0.6f;
            data.SetInstanceTransform(i, new Transform3D(Basis.Identity.Scaled(Vector3.One * 0.6f),
                new Vector3(x, y, 0)));
            data.SetInstanceCustomData(i, new Color(Mathf.PosMod(i * 0.6180339f, 1), 0.5f, 0, 1));
        }
        Multimesh = data;
        MaterialOverride = SwimMaterial;
        CastShadow = ShadowCastingSetting.Off;
        return true;
    }

    public void SetMotion(float clock, float amplitude)
    {
        SwimMaterial.SetShaderParameter("clock", clock);
        SwimMaterial.SetShaderParameter("amplitude", Mathf.Clamp(amplitude, 0, 0.4f));
    }
}

SchoolMesh.cs и SchoolShaders.cs берутся из общего примера. В custom data канал X задаёт фазу, Y — добавку к частоте. Позиции загружаются один раз; в каждом кадре меняется общий uniform clock, а не 2048 отдельных Transform из C#.

Полный vertex-шейдер

Шейдер
shader_type spatial;
render_mode unshaded, cull_disabled;
uniform float clock = 0.0;
uniform float amplitude = 0.22;
varying float shade;
void vertex() {
    float phase = INSTANCE_CUSTOM.x * TAU;
    float tail = clamp((0.6 - VERTEX.x) / 1.2, 0.0, 1.0);
    VERTEX.y += sin(clock * (2.0 + INSTANCE_CUSTOM.y) + phase + VERTEX.x * 4.0)
        * amplitude * tail * tail;
    shade = 0.65 + INSTANCE_CUSTOM.x * 0.35;
}
void fragment() {
    ALBEDO = vec3(shade * 0.84, shade * 0.91, shade);
}

VERTEX.x направлен вдоль тела. Множитель tail*tail удерживает голову и сильнее двигает хвост. INSTANCE_CUSTOM различается между экземплярами: общий материал не заставляет их колебаться синхронно. Пример не использует скелетную анимацию и не доказывает, что скелеты всегда медленнее.

Границы и разбиение группы

Изменение VERTEX на GPU не пересчитывает автоматически подходящие CPU-границы для всех положений анимации. CustomAabb здесь покрывает сетку расположений и запас на колебание. Слишком маленькие границы могут обрезать видимую стаю, слишком большие ухудшают отсечение.

Большая общая группа отсеивается как один объект. Если объекты распределены по большому уровню, создавайте пространственные группы с отдельными границами. Это разбиение отрисовки, не готовый стриминг мира и не индивидуальная игровая логика экземпляров.

GPU-движение · Оптимизация 3D

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.