Learn Unity shaders in HLSL

HLSL is the language of Unity's Built-in render pipeline and of DirectX. Every ShaderBattle lesson is written in HLSL first, so this is the most direct way to learn it: you write the fragment function in the browser, watch it run, and export it as a ready-to-use Unity shader.

Things to know about HLSL

  • Vectors are float2, float3 and float4; blend with lerp; frac is the fractional part.
  • Matrices multiply with mul(M, v), with the matrix first.
  • fmod(a, b) keeps the sign of a, so use abs() or add an offset when you work with negative numbers.
  • Unity gives you _Time.y for seconds and _ScreenParams for the screen size. The editor accepts them too.

Cheat sheet

IdeaWrite
Vectorsfloat2 float3 float4
Declare a valuefloat d = length(p);
A functionfloat circle(float2 p, float r) { ... }
Matricesfloat2x2, multiply with mul(M, v)
Blendlerp(a, b, t)
Fractional partfrac(x)
Clamp to 0..1saturate(x)
Remainderfmod(a, b) (keeps the sign of a)
Choosec ? a : b
Angle of a vectoratan2(y, x)
Time in secondstime, or Unity's _Time.y
Pixel positionuv (0..1, bottom-left)
Width / heightaspect, or _ScreenParams.x / _ScreenParams.y
Entry pointfloat4 frag(float2 uv) { return …; }

Handy built-ins: sin cos abs sign floor ceil frac step smoothstep clamp min max pow exp sqrt length distance dot cross normalize reflect

Gotchas

  • Every pixel runs on its own, with no memory of other pixels.
  • Declare a function above the place you use it.
  • Prefer 2.0 over 2 in maths. This site fixes most cases for you; real engines may not.
  • Loops need a small fixed count: for (int i = 0; i < 5; i++).

Example: a glowing ring

The same shader as it is written for Unity (Built-in):

float4 frag(float2 uv)
{
    float2 p = (uv - 0.5) * float2(aspect, 1.0);
    float d = length(p);
    float m = 1.0 - smoothstep(0.0, 0.02, abs(d - 0.3));
    float3 bg = float3(0.08, 0.08, 0.12);
    float3 fg = float3(0.4, 0.9, 1.0);
    return float4(lerp(bg, fg, m), 1.0);
}

Exporting to Unity

In Unity: Create → Shader → Unlit Shader, replace everything with this, then put a material using it on a Quad.

Shader "ShaderBattle/Glowing ring"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment fragMain
            #include "UnityCG.cginc"

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv  : TEXCOORD0;   // the mesh's UV: (0,0) bottom-left, (1,1) top-right
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord.xy;
                return o;
            }

            // Globals the website gives you for free:
            #define time _Time.y                    // seconds since start
            static const float aspect = 1.0;        // a Quad is square. (The website renders 4:3.)

            // ---- your code from ShaderBattle -------------------------------
            float4 frag(float2 uv)
            {
                float2 p = (uv - 0.5) * float2(aspect, 1.0);
                float d = length(p);
                float m = 1.0 - smoothstep(0.0, 0.02, abs(d - 0.3));
                float3 bg = float3(0.08, 0.08, 0.12);
                float3 fg = float3(0.4, 0.9, 1.0);
                return float4(lerp(bg, fg, m), 1.0);
            }
            // ----------------------------------------------------------------

            fixed4 fragMain (v2f i) : SV_Target
            {
                return frag(i.uv);
            }
            ENDCG
        }
    }
}

Questions

Is HLSL the same in Unity and Unreal?

The language is the same. What differs is how you get your code into the engine: a ShaderLab file in Unity, a Custom node in Unreal. Switch between the two in the language picker to see each export.

Do I need Unity installed to learn?

No. Everything runs in your browser. Install Unity only when you want to use what you built.

Other languages

Unity (URP) · Unreal · Shadertoy / WebGL · OpenGL (LWJGL, raylib) · three.js · GameMaker · LÖVE (Lua) · Godot · Apple (iOS, macOS) · WebGPU / Bevy