How to Create a Custom HUD or Sprite for Source Engine Games

Custom HUD elements and sprites are some of the most visible ways to personalize a Source Engine mod or map — crosshairs, health bar icons, damage indicators, muzzle flashes, and particle sprites all rely on the same underlying texture pipeline. Unlike world or model textures, HUD and sprite assets have their own set of rules around transparency, scaling, and file placement that trip up a lot of first-time modders.

This guide walks through creating a HUD element or sprite from a source image, converting it correctly, and getting it recognized by the engine.

Table of Contents

HUD Elements vs Sprites: What’s the Difference

These two terms get used interchangeably, but they behave differently in the engine:

  • HUD elements are 2D screen-space UI — crosshairs, health/ammo icons, damage numbers. These are typically referenced through resource files (.res) or scripts and rendered flat on the player’s screen regardless of camera angle.
  • Sprites are billboard textures rendered in 3D world space — muzzle flashes, particle effects, glow effects, tracer rounds. These use the .spr or particle system pipeline and always face the camera but exist as part of the 3D scene, not the screen overlay.

Both start from a VTF, but the VMT settings and file placement differ, which is covered separately below.

Designing Your Source Image

A few things matter more for HUD/sprite art than for standard world textures:

  • Transparency is essential. Almost every HUD element and sprite needs a genuine alpha channel — export your PNG with transparency preserved, not flattened against a solid background.
  • Design at the actual display size. HUD elements are typically small (icons in the 32×32 to 128×128 range) and rarely benefit from higher resolution, since screen-space UI doesn’t scale with distance the way world textures do.
  • Keep edges clean. Because HUD elements sit directly on top of gameplay at a fixed size, soft or blurry edges from upscaling or heavy compression are far more noticeable than they would be on a distant world texture.
  • Center your design carefully for sprites. Billboard sprites rotate to always face the camera, so off-center artwork can look wrong from certain angles — keep the visual weight centered in the canvas.

Converting to VTF for HUD/Sprite Use

The conversion settings for HUD and sprite textures differ slightly from standard world textures:

  • Compression: Use DXT5 if there’s any transparency gradient (soft glows, fading edges); use RGBA8888 (uncompressed) for very small icons where file size is negligible but crisp edges matter most, since DXT compression artifacts are more visible at small sizes with hard edges.
  • Mipmaps: Generally disable mipmaps for HUD elements — they’re rendered at a fixed screen size and don’t need distance-based scaling the way world textures do. Sprites in 3D space can keep mipmaps enabled.
  • Resolution: Match power-of-two dimensions (32, 64, 128, 256) for best engine compatibility, even though some newer engine branches tolerate non-power-of-two textures.

Creating the VMT for HUD Elements

HUD element VMTs typically use the UnlitGeneric shader, since screen-space UI shouldn’t be affected by in-game lighting:

"UnlitGeneric"
{
    "$basetexture" "hud/my_custom_icon"
    "$translucent" 1
    "$vertexalpha" 1
    "$vertexcolor" 1
    "$no_fullbright" 1
}

The $translucent flag is what allows the alpha channel to actually render as transparency rather than solid black or a hard cutout.

Creating the VMT for Particle Sprites

Particle sprites generally use UnlitGeneric as well, but often add additive blending for glow-style effects like muzzle flashes:

"UnlitGeneric"
{
    "$basetexture" "sprites/muzzleflash1"
    "$additive" 1
    "$vertexalpha" 1
    "$vertexcolor" 1
    "$halflambert" 0
}

$additive makes bright areas of the sprite glow against the background rather than simply overlaying — this is standard for flashes, glows, and light effects, but should be left off for sprites that need solid, non-glowing color.

File Placement

Placement conventions vary slightly by game, but the general pattern is:

  • HUD elements: [game]/materials/vgui/hud/ for most HL2-derived engine branches, referenced by a .res file in scripts/hud/ or through the mod’s UI resource scripts
  • Sprites: [game]/materials/sprites/ for particle and effect sprites, referenced either directly by particle system definitions or by legacy .spr wrapper files in older engine branches

Double-check your specific game’s existing HUD material paths (many are visible by extracting the game’s own VPK) to match the expected structure exactly — a HUD element sitting in the wrong subfolder will silently fail to load the same way world textures do.

Testing In-Game

  • For HUD elements, the fastest test loop is usually launching to the main menu or a test map and triggering the relevant UI state (taking damage, picking up ammo) rather than a full playtest each time.
  • For sprites, spawning the relevant effect via console commands (where the game supports it) is much faster than triggering it through normal gameplay.
  • Use mat_reloadallmaterials in the developer console after updating a VTF/VMT to force a refresh without fully restarting the game, where supported.

Common Mistakes

  • Forgetting $translucent or $vertexalpha in the VMT. Without these flags, an alpha channel in the VTF is effectively ignored and the element renders as a solid block instead of transparent.
  • Using mipmaps on HUD elements. This isn’t usually harmful, but it wastes file size on a texture that’s always rendered at a single fixed screen size.
  • Non-square or unusual resolutions for sprites. Some particle systems assume roughly square sprites for correct billboard rotation — heavily rectangular sprites can look stretched or distorted as they rotate to face the camera.
  • Wrong shader for the use case. Using a lit shader (like VertexLitGeneric, meant for 3D world models) on a HUD element can cause it to be affected by scene lighting in unexpected ways instead of rendering as flat, consistent UI.

FAQ

Do HUD elements need mipmaps? Generally no. HUD elements render at a fixed screen size regardless of distance, so mipmaps add file size without providing any visual benefit.

Why does my sprite look like a solid black square instead of transparent? This almost always means the VMT is missing $translucent 1 (or $alphatest for hard-edged cutouts), so the engine isn’t reading the alpha channel as transparency at all.

Can I use the same VTF for both a HUD icon and a world texture? Technically yes, since it’s the same file format, but the ideal compression, mipmap, and resolution settings differ enough between the two use cases that it’s usually better to convert separate versions optimized for each purpose.

What resolution should a crosshair or small HUD icon be? Most crosshairs and small icons work well at 32×32 to 64×64 — going much higher provides no visible benefit since they’re rendered small and don’t scale with camera distance.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top