reckfellENGINE

GPU particles: moving a visual school

The process shader updates TRANSFORM; the mesh shader reads CUSTOM through INSTANCE_CUSTOM.

On this page

What changes from MultiMesh

Set ParticleMotion=true before launching the combined example. GpuParticles3D manages particle lifetime and instances while the process shader writes their transforms on the GPU. The previous guide's vertex shader separately bends the tail.

Actual rendering of 2,048 instances

ParticleSchool3D.cs
C#
using Reckfell;

public partial class ParticleSchool3D : GpuParticles3D
{
    public ShaderMaterial SwimMaterial { get; private set; } = null!;
    public ShaderMaterial MotionMaterial { 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 } };
        MotionMaterial = new ShaderMaterial { Shader = new Shader { Code = SchoolShaders.Motion } };
        MotionMaterial.SetShaderParameter("columns", layout.Columns);
        MotionMaterial.SetShaderParameter("rows", layout.Rows);
        Amount = count;
        Lifetime = 60;
        Explosiveness = 1;
        FixedFps = 30;
        UseFixedSeed = true;
        Seed = 42;
        LocalCoords = true;
        VisibilityAabb = layout.Bounds.Grow(0.5f);
        DrawPass1 = SchoolMesh.Create();
        MaterialOverride = SwimMaterial;
        ProcessMaterial = MotionMaterial;
        CastShadow = ShadowCastingSetting.Off;
        Emitting = true;
        Restart();
        return true;
    }

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

Complete process shader

Shader
shader_type particles;
render_mode disable_force, disable_velocity;
uniform float clock = 0.0;
uniform int columns = 32;
uniform int rows = 16;
void start() {
    CUSTOM = vec4(fract(float(INDEX) * 0.6180339), 0.5, 0.0, 1.0);
    COLOR = vec4(1.0);
}
void process() {
    float phase = CUSTOM.x * TAU;
    float x = (float(INDEX % uint(columns)) - float(columns - 1) * 0.5) * 0.85;
    float y = (float(INDEX / uint(columns)) - float(rows - 1) * 0.5) * 0.6;
    TRANSFORM = mat4(vec4(0.6, 0.0, 0.0, 0.0), vec4(0.0, 0.6, 0.0, 0.0),
        vec4(0.0, 0.0, 0.6, 0.0),
        vec4(x + sin(clock + phase) * 0.35, y + cos(clock + phase) * 0.12, 0.0, 1.0));
}

start initializes CUSTOM phase for INDEX; process writes position into TRANSFORM. The mesh shader reads CUSTOM through INSTANCE_CUSTOM. NUMBER and INDEX are not permanent gameplay IDs: particles restart and reuse slots.

disable_velocity prevents additional VELOCITY integration because the shader already computes position. C# supplies clock; there is no individual pathfinding, collision, schooling behavior or gameplay access to every position.

Settings and bounds

DrawPass1 holds the original mesh, ProcessMaterial the particles shader and MaterialOverride its spatial drawing shader. UseFixedSeed and Seed help reproducibility; this shader additionally uses deterministic INDEX. Lifetime=60 and Explosiveness=1 configure a burst rather than immortal game characters.

VisibilityAabb covers the motion area plus margin. CaptureAabb reads GPU state and can lag several frames; Compatibility additionally expands its estimate by mesh size. Do not call it every frame for ordinary culling or treat a snapshot as coverage for all future positions and vertex deformation.

Check the rendering method

This example was rendered with Compatibility/OpenGL. That does not imply support for every particle feature: this path does not support trails, sub-emitters or manual EmitParticle. Driver-specific restrictions may also disable GPU particles. Verify required features and export separately on another platform.

Mesh shader · GPU constraints

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.