Core first, noise second
A beam needs a strong center line before it needs detail. If the core is weak, extra noise and bloom only make the shot harder to read.
UE5 / Recipe / Stylized VFX
A stylized beam material for lasers, magic channels, charged attacks, and projectile trails. The recipe focuses on a clean core, readable falloff, directional flow, and controlled HDR emission.
A beam needs a strong center line before it needs detail. If the core is weak, extra noise and bloom only make the shot harder to read.
01
02
03
Think of it as a long rectangle with a center mask across width and a flow mask along length. Width controls readability. Length motion controls energy direction.
The beam should still have a core and falloff in grayscale. Bloom can make it feel powerful, but it should not be the only reason the beam is visible.
04
Use one axis for beam length and one for width. Keep this convention consistent across beam materials so artists can reuse textures and masks.
Start with a simple centerline falloff. The center should be strong, the edge should fade gently, and the width should be adjustable.
Pan streak noise along the beam length. This is what tells the viewer which direction the energy is moving.
The core can be sharp and bright. The outer glow should be softer and wider. Treat them as two layers, even if they share the same UVs.
Endpoint glow is useful for lasers and channel spells, but not every beam needs it. Keep it optional so the same material can support loops and one-shots.
05
06
float widthCoord = abs(uv.y * 2.0 - 1.0);
float coreMax = coreWidth + coreSoftness;
float core = 1.0 - smoothstep(coreWidth, coreMax, widthCoord);
float outerMax = outerWidth + outerSoftness;
float outer = 1.0 - smoothstep(outerWidth, outerMax, widthCoord);
float2 flowUV = float2(uv.x * flowTiling - time * flowSpeed, uv.y);
float streaks = Texture2DSample(flowTex, flowTexSampler, flowUV).r;
streaks = saturate((streaks - streakBias) * streakContrast + 0.5);
float impact = 1.0 - smoothstep(0.0, impactFalloff, uv.x);
float mask = core + outer * outerStrength;
mask += streaks * flowStrength + impact * impactStrength;
mask = saturate(mask);
float3 color = coreColor * core + edgeColor * outer + impactColor * impact;
float3 emissive = color * mask * emissionStrength;
return float4(emissive, mask);
07
The material is only half the recipe. You need predictable UVs, stable width, and clean endpoints. Bad mesh UVs make even a good beam graph feel broken.
Width, length, flow speed, color, and endpoint intensity are good Niagara user parameters. Avoid exposing tiny internal math values to VFX artists.
If the beam passes through geometry, decide whether it should clip, fade, spark, or create an impact mask. Do not leave intersections accidental.
08