Shader Story

August 1, 2025 ยท View on GitHub

Patterns & Shapes: Line

fwidth() and saturate() are used to define a crisp, antialiased line in UV space.
Good for for stylized masks, transitions, scanlines, or any UI elements requiring crisp anti-aliasing.

half2 uvs = abs(uv + float2(-offsetX, 0.0)) - float2(width, 1.0);
half2 mask_line = 1 - (uvs / fwidth(uvs));
half col_output = saturate(min(mask_line.x, mask_line.y));

Visual demo

This pattern draws a centered vertical line based on a horizontal offset and customizable width. Shape is created by using fwidth() for screen-space derivatives and saturate() to clamp the result.

Shader Story: Patterns - Line


URP Shader Code


Shader "DecompiledArt/Patterns/Line/Line"
{
    Properties
    {
        _Offset_X("Offset_X", Float) = 0.5
        _Line_Width("Line_Width", Range(0.0, 0.5)) = 0.2
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {            
            ...
            

            half4 frag(Varyings IN) : SV_Target
            {
                half2 uvs = abs(IN.uvs + half2(mul(_Offset_X, -1.0), 0.0)) - half2(_Line_Width, 1.0);
                half2 mask_line = 1 - (uvs / fwidth(uvs));

                half col_output = saturate(min(mask_line.x, mask_line.y));

                return half4(col_output.xxx, 1.0);
            }

            ENDHLSL
        }
    }
}

URP Shader graph

Shader Story: Patterns - Line


Clamp/Saturate โ€ข Smoothstep


โค๏ธ Support Shader Story

If this article helped you, consider supporting the project on Patreon - you'll get access to the related source files, reference cheat-sheets, and other exclusive resources:

DecompiledArt on Patreon

Your support helps keep this library open, growing, and free for everyone.