graphics programming
neon glow effects
algorithm design
digital art
visual effects

Algorithm for neon glow graphics programming

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A convincing neon glow effect is not just "draw a bright line and blur it a little." Good neon rendering separates the sharp luminous core from the soft halo around it, then combines them in a way that preserves contrast and color intensity.

Think in Passes, Not in One Shader

The most practical neon pipeline uses multiple render passes:

  1. Render the source shape or text at full brightness.
  2. Extract the emissive part that should glow.
  3. Blur that emissive texture.
  4. Add the blurred halo back on top of the sharp original.

This is basically a targeted bloom effect. The reason it works is that real neon signs have a crisp tube in the center and a wider light spill around it. If you blur the whole image equally, the effect looks muddy instead of luminous.

Build the Bright Core First

Start by rendering the shape you want to glow. For a neon sign, the core should already be saturated and bright.

glsl
1#version 300 es
2precision mediump float;
3
4uniform vec3 uColor;
5out vec4 outColor;
6
7void main() {
8    outColor = vec4(uColor, 1.0);
9}

This core pass should stay fairly thin and well-defined. If the source art is too thick, the later blur spreads too much and the result looks like fog rather than neon.

In many engines you will render this core to an off-screen texture instead of directly to the final framebuffer. That gives you something clean to feed into the glow pass.

Blur the Emissive Texture Efficiently

The glow halo is usually produced with Gaussian blur. A naive two-dimensional blur is expensive, so most real-time renderers use a separable blur:

  • one horizontal pass
  • one vertical pass

That reduces the cost significantly while looking almost the same.

glsl
1#version 300 es
2precision mediump float;
3
4uniform sampler2D uTexture;
5uniform vec2 uTexelSize;
6uniform vec2 uDirection;
7
8in vec2 vUV;
9out vec4 outColor;
10
11void main() {
12    vec4 sum = texture(uTexture, vUV) * 0.227027;
13    sum += texture(uTexture, vUV + uDirection * uTexelSize * 1.384615) * 0.316216;
14    sum += texture(uTexture, vUV - uDirection * uTexelSize * 1.384615) * 0.316216;
15    sum += texture(uTexture, vUV + uDirection * uTexelSize * 3.230769) * 0.070270;
16    sum += texture(uTexture, vUV - uDirection * uTexelSize * 3.230769) * 0.070270;
17    outColor = sum;
18}

Run this shader twice. First set uDirection to horizontal, then vertical. The result is a soft halo texture.

Composite with Additive Blending

Once you have a blurred halo texture, combine it with the sharp core. Additive blending is the usual choice because it increases brightness naturally:

glsl
1#version 300 es
2precision mediump float;
3
4uniform sampler2D uCore;
5uniform sampler2D uGlow;
6
7in vec2 vUV;
8out vec4 outColor;
9
10void main() {
11    vec4 core = texture(uCore, vUV);
12    vec4 glow = texture(uGlow, vUV);
13    outColor = core + glow * 1.5;
14}

The glow multiplier controls how dramatic the effect feels. Low values look subtle and polished. High values create the exaggerated arcade-style neon many games and posters want.

Add Color Falloff and Layered Halos

A more interesting neon effect often uses two or three glow layers instead of one:

  • a tight bright halo near the source
  • a wider softer halo farther out
  • sometimes a faint colored bloom on top

You can create this by blurring at different radii or by downsampling before the blur to get a larger spread cheaply.

For example:

  • small blur for the intense inner aura
  • larger blur for the atmospheric outer glow

Then add both back during compositing. This layered approach looks much richer than a single blur radius.

Color choice matters too. Neon usually looks best when the glow color matches the core but fades slightly toward darker saturated tones rather than plain white. If every part of the halo stays equally bright, the effect becomes flat.

Use Distance Fields for Crisp Neon Text

If you are rendering neon text or vector-like icons, signed distance fields are useful. They let you keep a crisp inner edge while generating a soft outer glow from the distance value.

glsl
float d = texture(uDistanceField, vUV).r;
float coreMask = smoothstep(0.48, 0.52, d);
float glowMask = smoothstep(0.30, 0.52, d);

From there, you can color the core and the glow differently. This is a common approach for scalable neon labels in UI, games, and stylized scenes.

Performance Notes

Glow effects are fill-rate heavy, so optimization matters:

  • blur at half or quarter resolution
  • use separable blur instead of full kernels
  • only blur emissive objects, not the entire scene
  • avoid extremely large radii unless the effect is central to the frame

These tradeoffs are why production glow systems are often built as post-processing passes around emissive masks rather than per-object custom shading alone.

Common Pitfalls

  • Blurring the full scene instead of just the emissive areas, which makes everything look washed out.
  • Using only one huge blur radius, which produces a cloudy blob instead of neon.
  • Forgetting color management, so the glow clips to flat white too early.
  • Making the core too soft. Real neon still needs a sharp center.
  • Running the blur at full resolution when a lower-resolution glow buffer would look almost identical.

Summary

  • Good neon rendering separates the sharp core from the soft halo.
  • A practical algorithm is emissive render pass, blur pass, then additive composite.
  • Separable Gaussian blur is the standard efficient way to build the halo.
  • Multiple blur radii often look better than a single glow layer.
  • The best results come from balancing crisp source shapes with controlled, colored light spread.

Course illustration
Course illustration

All Rights Reserved.