Particle trails: history, ribbons and tubes
Working setup, history versus geometry, poses and cost.
A particle trail deforms geometry along particle history. It needs all three pieces: emitter trail history, a mesh with appropriate trail poses, and a surface material that uses particle trails. A long unskinned mesh alone is not a historical motion trail.
Configure a ribbon
- Use the supported rendering path. The current workflow is for Forward+/Mobile; the native example is verified on Windows Forward+/Vulkan.
- Give GpuParticles3D a process material and visible movement. Enable Trails → Enabled and set Trail Lifetime.
- Assign RibbonTrailMesh to a draw pass, with a suitable width and section layout.
- On its StandardMaterial3D enable Use Particle Trails. Inspect MaterialOverride too: an override can replace the surface configuration you thought was active.
- Choose alignment for the intended motion, then set VisibilityAabb large enough for the path and its trailing history.
Run the C# ribbon
using Reckfell;
public static class ParticleRibbon
{
public static GpuParticles3D Create()
{
var surface = new StandardMaterial3D
{
ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded,
AlbedoColor = Colors.White,
UseParticleTrails = true,
CullMode = BaseMaterial3D.CullModeEnum.Disabled,
};
var ribbon = new RibbonTrailMesh
{
Shape = RibbonTrailMesh.ShapeEnum.Flat,
Size = 0.12f, Sections = 8, SectionLength = 0.1f,
SectionSegments = 2, Material = surface,
};
return new GpuParticles3D
{
Emitting = false, OneShot = true, Amount = 1, Lifetime = 2,
Explosiveness = 1, FixedFps = 60,
TrailEnabled = true, TrailLifetime = 0.4,
TransformAlign = GpuParticles3D.TransformAlignEnum.YToVelocity,
ProcessMaterial = new ParticleProcessMaterial
{
Direction = Vector3.Up, Spread = 0, Gravity = Vector3.Zero,
InitialVelocityMin = 1f, InitialVelocityMax = 1f,
},
DrawPass1 = ribbon,
VisibilityAabb = new Aabb(new Vector3(-3, -3, -3), new Vector3(6, 6, 6)),
};
}
}Add ParticleRibbon.Create() to the intended world and call Restart on the returned emitter. Provide an active camera covering it. This is a functional ribbon with an unshaded double-sided material, not a finished smoke/ribbon asset or a beauty illustration. The test also renders a TubeTrailMesh using the same trail-enabled material.
The example has a particle Lifetime of 2 seconds and a TrailLifetime of 0.4 seconds. These are different settings: the first governs particle life, the second historical duration. Do not change particle Lifetime when you mean to change history length.
Separate time history from rest geometry
| Setting | Controls |
|---|---|
| TrailLifetime | How much history the trail uses. Together with motion, affects its visible path length. |
| Sections | Trail mesh sections and built-in pose layout. |
| SectionLength | Rest length of each mesh section; not a universal final world-space trail length. |
| Ribbon SectionSegments / tube SectionRings | Geometry subdivisions within sections. |
| Ribbon Size / tube Radius | Cross-section width/radius. |
| Tube RadialSteps | Circumference detail and vertex cost. |
| Curve | Width/radius profile along the generated mesh. Not the particle's motion curve. |
Sections × SectionLength describes the generated rest mesh. It does not guarantee that the final deformed trail is that many world units long. In the native test, changing history duration increases the visible trail span without changing that rest product. For steady travel, speed × history duration is a useful starting intuition, not an exact length guarantee for every curve, step or deformation.
More geometry can smooth a profile/bend but does not create missing simulation history or collision steps. The test confirms increased ribbon/tube vertex counts after adding subdivisions; it does not claim an automatic visual-quality improvement for every scene.
Use compatible poses and alignment
RibbonTrailMesh and TubeTrailMesh provide built-in trail poses. A custom DrawSkin can override them; do not assign an unrelated skin and expect both layouts to combine automatically. Multiple draw passes with incompatible pose layouts need a deliberate setup.
Ribbon Flat is a single ribbon; Cross provides crossed geometry for more view angles. Surface culling, billboard behavior and camera angle still affect visibility. Tube trails need appropriate orientation as the path changes; YToVelocity is the example's starting alignment, not proof of artifact-free behavior on every curved or stationary trajectory.
For transparency, configure the surface's actual alpha mode and sorting. Trail history does not provide order-independent blending. A visible unshaded test does not validate the normals, lighting, texture seams or transparency of the finished asset.
Keep history changes intentional
In the current RenderingDevice implementation, changing trail enable/duration frees particle data and resets phase for reallocation. Do not repeatedly assign these controls every frame as a cheap fade animation. Changing mesh pose count can also require data rebuilding.
The backend caps historical duration at 10 seconds and rejects values below approximately 0.01 seconds; keep authored values in the supported range. The scene TrailLifetime getter stores the request and does not prove that a longer requested duration allocated more history. This cap is source-reviewed; the example does not run a ten-second acceptance test.
History and mesh cost depend on particle capacity, simulation frequency, history duration and pose/vertex counts. Measure representative overlapping trails. Lowering geometry subdivisions and lowering simulation frequency solve different costs and have different visual consequences.
Diagnose broken trails
| Symptom | Check |
|---|---|
| No proper deformation | TrailEnabled, trail mesh/poses and UseParticleTrails on the effective surface/override. |
| Trail cuts off near the camera edge | VisibilityAabb includes history, not only the current head. |
| Length differs from Sections × SectionLength | Rest geometry is not the final motion-history length. |
| Flat ribbon vanishes from the side | Camera angle, culling and Flat/Cross or billboard choice. |
| Bent tube flattens or twists | Alignment, path, pose layout and section detail; inspect motion. |
| Repeated resets or loading spikes | Repeated history/pose changes and excessive history/geometry. |
Native coverage includes ribbon/tube pixels, rest-layout values, subdivision counts, history-duration span change and stable frozen trail pixels. Curved-path quality, custom skins, transparent moving-camera cases, other hardware/renderers, exports and performance remain separate validation.