Niagara and VFX

Five VFX events, deterministic weighted Niagara variation, wood splinters that take on the broken object's texture and never hang in the air, external presentation listeners and the built-in spawn budget.

The five events

ESDFVFXEvent:

EventEmitted when
LightImpactA valid hit below the profile’s heavy VFX thresholds
HeavyImpactA hit at or above HeavyImpactVFXMinimumPower or HeavyImpactVFXMinimumImpulse
BreakThe object is destroyed
DebrisImpactA debris piece collides fast enough
CustomRequested explicitly by your own code, with a name

Custom is what makes the VFX layer extensible without touching the framework: your gameplay can request a named effect through the same deterministic, budgeted path as the built-in events.

Weighted variations

Each event reads an array of FSDFWeightedNiagaraSystem:

PropertyDefaultMeaning
SystemnoneSoft UNiagaraSystem reference
Weight1.0Relative selection weight
MinimumScale0.9Lower bound of the random scale
MaximumScale1.1Upper bound
bOrientToImpactNormaltrueAlign the system’s local Z axis to the impact normal
RotationOffsetzeroRotation applied after orientation

Soft references mean the Niagara assets are loaded on demand, not pinned by every profile that mentions them. Empty and zero-weight entries are ignored safely.

Orientation

With bOrientToImpactNormal enabled, the system’s local Z axis is aligned to ImpactNormal, then RotationOffset is applied. That is the behaviour you want for surface-hugging effects — dust puffs, splinter sprays, chips.

Disable it for effects authored in world space, such as a volumetric burst that should always rise vertically regardless of which face was hit.

Splinters that look like the object

The supplied wood break effect (NS_SDF_Impact_Wood, used by every wood preset) makes its splinters and chips belong to the object that broke:

  • They start where you struck it and burst up and along the swing — never back into the object, where a tall prop’s back or openings would catch them.
  • They never hang in the air. Splinters collide on the Camera trace channel, which every SDF debris body ignores: they fly through the broken pieces and land on the real floor. A splinter that still stalls above the floor the object stood on is removed, and every splinter shrinks away at the end of its life instead of popping.
  • They take on the object’s look. Splinters show the object’s own base colour texture, each from a different spot; chips are tinted from it and keep their shapes. A light oak bench throws light oak splinters.

How the texture is found

  1. When SDF generates, regenerates or modifies a destructible, it records the texture wired into the dominant material’s Base Color in the profile’s SourceAppearance (FSDFDebrisAppearance: BaseColorTexture, AverageColor, bValid).
  2. Without a recorded texture, SDF inspects the material at runtime and keeps colour textures only — sRGB, not normal, roughness, AO or mask maps, not virtual — preferring names such as BaseColor, Albedo, Diffuse, _BC or _D.
  3. When nothing qualifies, the splinters keep the supplied wood look.

The texture feeds SDF’s own particle materials, M_SDF_WoodSplinter_Source and M_SDF_WoodChip_Source. The object’s material is never put on particles: a material without the Niagara usage flags renders as the grey default checker in a cooked game.

User parameters written on every built-in spawn

SDF sets these on the spawned component before it activates. Systems that do not declare them ignore them.

NameTypeMeaning
SDFImpactDirectionVector3Hit direction blended with the surface normal
SDFImpactStrengthFloatDestruction Power: VeryLight 0.6, Light 0.85, Medium 1.0, Heavy 1.4, Massive 1.8
SDFRandomSeedInt32Seed carried by the request
SDFSplinterOriginPositionThe struck point (break location when the hit carried none)
SDFSplinterDirectionVector3Burst direction: up, along the swing, a little out of the struck face
SDFBoundsMin, SDFBoundsMaxPositionWorld bounds of the intact object; SDFBoundsMin.Z is the floor it stood on
SDFSourceBaseColorTextureThe object’s base colour texture, or none
SDFUseSourceTextureFloat1 when a texture was found, else 0
SDFSourceColorLinear ColorAverage colour of that texture, recorded at authoring

For a duplicated wood system, keep the emitter names NE_SDF_Splinters and NE_SDF_WoodChips and run the editor command SDF.Dev.SetupSplinterEffect /Game/Path/NS_YourWood.NS_YourWood. It wires the texture user parameter into the renderers’ material bindings and saves the system.

Pass user parameters as module inputs

The supplied splinter modules receive User. values through module inputs bound to the user parameters, not by reading them inside custom HLSL. Keep those bindings when editing, and recompile after every change: one emitter that fails to compile stops the whole effect.

Deterministic selection

SelectWeightedVFXVariation(Variations, RandomSeed, OutScale, OutRotation, ImpactNormal, ImpactDirection) is a pure, static, Blueprint-callable function. The same seed yields the same system, scale and rotation.

Built-in spawning versus delegates

PropertyEffect
bEnableVFXRequestsMaster switch: emit VFX requests at all
bEnableBuiltInVFXSpawningAlso spawn the selected Niagara system directly

Requests are always emitted

As with audio, disabling built-in spawning keeps the requests flowing. An external presentation system receives a fully resolved selection — system, scale, rotation, seed — and decides what to do with it.

The request payload

FSDFDestructionVFXRequest:

FieldMeaning
EventWhich of the five events
CustomEventNameSemantic identifier, meaningful for Custom
SourceActorThe destructible
LocationWorld position
ImpactNormalSurface normal used for orientation
ImpactDirectionDirection of the causing hit
RotationResolved rotation
ScaleResolved scale
ImpactSpeedSpeed associated with the event
DestructionPowerPower of the causing hit
SelectedSystemThe Niagara variation picked
RandomSeedSeed used
SelectedVariationIndexIndex into the profile array
bBuiltInSpawnRequestedBuilt-in spawning was configured
bBuiltInSpawnAttemptedA spawn was actually attempted
bBuiltInSpawnSuppressedByBudgetThe per-frame built-in VFX budget suppressed it
SplinterOriginWhere splinters start: the struck point on a break
SplinterDirectionBurst direction for splinters
SourceBoundsWorld bounds of the intact object
AppearanceFSDFDebrisAppearance of the broken object (texture, average colour, valid flag)

Requesting a custom effect

RequestVFXEvent(Event, Location, ImpactNormal, ImpactDirection, ImpactSpeed, DestructionPower, RandomSeed, CustomName) on the destructible component resolves and emits one request. Pass Custom with a CustomName that your presentation system understands, and populate CustomEffects on the profile if you also want built-in spawning.

DestructibleComponent->RequestVFXEvent(
    ESDFVFXEvent::Custom,
    ImpactLocation,
    ImpactNormal,
    ImpactDirection,
    /* ImpactSpeed */ 0.f,
    ESDFDestructionPower::Medium,
    /* RandomSeed */ -1,
    TEXT("EmberBurst"));

Where to listen

ScopeDelegate
One objectUSDFDestructibleComponent::OnDestructionVFXRequested
Whole worldUSDFDestructionSubsystem::OnDestructionVFXRequested

The global delegate is the correct integration point for a pooled particle manager or a custom Niagara routing layer.

Debris impact VFX

Throttled by the same three-property pattern as audio:

  • MinimumDebrisImpactVFXSpeed (default 200.0);
  • DebrisImpactVFXCooldown (default 0.15 s);
  • MaximumDebrisImpactVFXPerDebrisActor (default 1).

VFX budget

MaxBuiltInVFXEventsPerFrame (default 64) caps built-in spawning only. External listeners keep receiving every request.

GetVFXStats returns FSDFDestructionVFXStats with TotalRequests, TotalBuiltInSpawnAttempts, TotalBuiltInSpawnsSuppressed and BuiltInSpawnAttemptsThisFrame. GetLastVFXRequest returns the most recent payload; ResetVFXStatistics clears the counters.

Budget your own spawns too

If you route VFX to your own system and disable built-in spawning, the framework’s VFX budget no longer protects you. Apply your own cap in the listener — a large radial event can legitimately produce dozens of requests in one frame.

Last updated: 2026-10-01

Type to search titles, sections and keywords.