Elysia Tools

Browse tools, examples, visual explainers, and topic guides from one clear workspace.

Top Categories

Hubs

Language
ZHESPTRUFRDEEN

Elysia Tools

Navigation

Game Development

Unity Shader Samples

Unity HLSL shader examples including surface shaders, vertex/fragment shaders, and post-processing effects

Samples

Entries inside this sample collection

CodeglslSimple

Basic Unity Shaders

Introduction to Unity shader programming with surface shaders and basic effects

Difficulty

4/10

Estimated time

25 min

Tags

unity, shader, hlsl, graphics

Prerequisites

Shader programming basics, Unity Editor

glsl
// Unity Basic Shaders - HLSL/Cg

// 1. Basic Diffuse Shader
Shader "Custom/BasicDiffuse"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        fixed4 _Color;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

// 2. Lambert Lighting with Custom Properties
Shader "Custom/CustomLambert"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _Emission ("Emission", Color) = (0,0,0,1)
        _Glossiness ("Glossiness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex;
        fixed4 _Color;
        half _Glossiness;
        half _Metallic;
        fixed4 _Emission;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Normal = fixed3(0,0,1);
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Emission = _Emission.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Standard"
}

// 3. Transparent Shader with Alpha
Shader "Custom/Transparent"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _Alpha ("Alpha", Range(0,1)) = 1.0
    }

    SubShader
    {
        Tags {
            "Queue"="Transparent"
            "RenderType"="Transparent"
        }

        LOD 100
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Cull Off

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

        sampler2D _MainTex;
        fixed4 _Color;
        float _Alpha;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a * _Alpha;
        }
        ENDCG
    }
}

// 4. Rim Lighting Shader
Shader "Custom/RimLighting"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _RimColor ("Rim Color", Color) = (0,0.5,1,1)
        _RimPower ("Rim Power", Range(0,8)) = 3.0
    }

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

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        fixed4 _Color;
        fixed4 _RimColor;
        float _RimPower;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;

            // Rim lighting
            half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
            o.Emission = _RimColor.rgb * pow (rim, _RimPower);
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

// 5. Toon/Cel Shading Shader
Shader "Custom/ToonShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _Ramp ("Toon Ramp", 2D) = "gray" {}
        _OutlineColor ("Outline Color", Color) = (0,0,0,1)
        _Outline ("Outline Width", Range(0,0.1)) = 0.02
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        UsePass "Toon/OUTLINE"

        CGPROGRAM
        #pragma surface surf Toon

        sampler2D _MainTex;
        sampler2D _Ramp;
        fixed4 _Color;

        struct Input
        {
            float2 uv_MainTex;
        };

        inline fixed4 LightingToon (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
        {
            half d = dot (s.Normal, lightDir) * 0.5 + 0.5;
            fixed3 ramp = tex2D (_Ramp, fixed2(d,d)).rgb;
            fixed4 c;
            c.rgb = s.Albedo * _LightColor0.rgb * ramp * atten;
            c.a = s.Alpha;
            return c;
        }

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }

    Fallback "Diffuse"
}

// 6. Scrolling Texture Shader
Shader "Custom/ScrollingTexture"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _ScrollX ("Scroll X Speed", float) = 0.1
        _ScrollY ("Scroll Y Speed", float) = 0.0
    }

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

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        fixed4 _Color;
        float _ScrollX;
        float _ScrollY;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float2 scrolledUV = IN.uv_MainTex;
            scrolledUV.x += _Time.y * _ScrollX;
            scrolledUV.y += _Time.y * _ScrollY;

            fixed4 c = tex2D (_MainTex, scrolledUV) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

// 7. Dissolve Shader
Shader "Custom/Dissolve"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _DissolveTex ("Dissolve Texture", 2D) = "white" {}
        _DissolveAmount ("Dissolve Amount", Range(0,1)) = 0.0
        _EdgeColor ("Edge Color", Color) = (1,0,0,1)
        _EdgeWidth ("Edge Width", Range(0,0.1)) = 0.01
    }

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

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        sampler2D _DissolveTex;
        fixed4 _Color;
        float _DissolveAmount;
        fixed4 _EdgeColor;
        float _EdgeWidth;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_DissolveTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float dissolve = tex2D (_DissolveTex, IN.uv_DissolveTex).r;

            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

            if (dissolve < _DissolveAmount)
            {
                clip (-1);
            }

            // Edge effect
            if (dissolve < _DissolveAmount + _EdgeWidth)
            {
                c = _EdgeColor;
            }

            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

// 8. Glass/Refraction Shader
Shader "Custom/Glass"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _BumpMap ("Normal Map", 2D) = "bump" {}
        _Color ("Color", Color) = (1,1,1,1)
        _RefractAmount ("Refraction Amount", Range(0,1)) = 0.5
        _Glossiness ("Glossiness", Range(0,1)) = 0.8
    }

    SubShader
    {
        Tags {
            "Queue"="Transparent"
            "RenderType"="Opaque"
        }

        GrabPass {}

        CGPROGRAM
        #pragma surface surf Standard alpha
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpMap;
        sampler2D _GrabTexture;
        fixed4 _Color;
        float _RefractAmount;
        half _Glossiness;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float4 screenPos;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

            // Refraction
            float3 normal = UnpackNormal(tex2D (_BumpMap, IN.uv_BumpMap));
            float2 offset = normal.xy * _RefractAmount;
            IN.screenPos.xy += offset;

            half3 grabColor = tex2Dproj(_GrabTexture, IN.screenPos).rgb;

            o.Albedo = c.rgb;
            o.Emission = grabColor * _RefractAmount;
            o.Smoothness = _Glossiness;
            o.Normal = normal;
            o.Alpha = c.a * 0.8;
        }
        ENDCG
    }
    Fallback "Transparent/Cutout/VertexLit"
}

// 9. Vertex/Fragment Shader - Basic Unlit
Shader "Custom/BasicUnlit"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv) * _Color;
                return col;
            }
            ENDCG
        }
    }
}

// 10. Vertex Color Shader
Shader "Custom/VertexColor"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = v.color;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
CodeglslIntermediate

Advanced Unity Shaders

Complex shader effects including parallax mapping, tessellation, and advanced lighting models

Difficulty

7/10

Estimated time

35 min

Tags

unity, shader, advanced, parallax, tessellation

Prerequisites

Advanced shader programming, Mathematics, Graphics pipeline

glsl
// Advanced Unity Shaders - HLSL/Cg

// 1. Parallax Occlusion Mapping Shader
Shader "Custom/ParallaxOcclusion"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap ("Normal Map", 2D) = "bump" {}
        _ParallaxMap ("Height Map", 2D) = "black" {}
        _Parallax ("Height Scale", Range(0.005, 0.08)) = 0.02
        _ParallaxMaxSteps ("Max Steps", Range(1, 50)) = 20
        _ParallaxRefractionSteps ("Refraction Steps", Range(1, 20)) = 10
        _Color ("Color", Color) = (1,1,1,1)
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Glossiness ("Glossiness", Range(0,1)) = 0.5
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 300

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0
        #pragma shader_feature _PARALLAX_MAP

        sampler2D _MainTex;
        sampler2D _BumpMap;
        sampler2D _ParallaxMap;
        fixed4 _Color;
        half _Metallic;
        half _Glossiness;
        float _Parallax;
        int _ParallaxMaxSteps;
        int _ParallaxRefractionSteps;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float2 uv_ParallaxMap;
            float3 viewDir;
        };

        #if defined(_PARALLAX_MAP)
            float2 ParallaxOffset(float2 uv, float3 viewDir)
            {
                float h = tex2D(_ParallaxMap, uv).r;
                float height = h * _Parallax;
                float2 offset = viewDir.xy / (viewDir.z + 0.42);
                return uv - offset * height;
            }

            float2 RaymarchParallax(float2 uv, float3 viewDir)
            {
                float2 offset = 0;
                float stepSize = 1.0 / _ParallaxMaxSteps;

                for(int i = 0; i < _ParallaxMaxSteps; i++)
                {
                    float h = tex2D(_ParallaxMap, uv + offset).r;
                    float height = h * _Parallax;

                    if(height > (float)i / _ParallaxMaxSteps)
                    {
                        offset -= viewDir.xy / viewDir.z * stepSize * _Parallax;
                    }
                    else
                    {
                        break;
                    }
                }

                return uv + offset;
            }
        #endif

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            #if defined(_PARALLAX_MAP)
                float2 uv = RaymarchParallax(IN.uv_ParallaxMap, IN.viewDir);
            #else
                float2 uv = IN.uv_MainTex;
            #endif

            fixed4 c = tex2D (_MainTex, uv) * _Color;
            o.Albedo = c.rgb;
            o.Normal = UnpackNormal(tex2D (_BumpMap, uv));
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Standard"
}

// 2. Tessellation Shader
Shader "Custom/Tessellation"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _Tessellation ("Tessellation", Range(1,32)) = 4
        _MinDistance ("Min Distance", Range(1,20)) = 10
        _MaxDistance ("Max Distance", Range(20,100)) = 50
        _EdgeLength ("Edge Length", Range(2,50)) = 15
    }

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

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows vertex:disp tessellate:tessEdge nolightmap
        #pragma hull hull_shader
        #pragma domain domain_shader
        #pragma target 4.6

        sampler2D _MainTex;
        fixed4 _Color;
        float _Tessellation;
        float _MinDistance;
        float _MaxDistance;
        float _EdgeLength;

        struct appdata
        {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float4 vertex : SV_POSITION;
            float3 normal : NORMAL;
            float2 uv : TEXCOORD0;
        };

        float4 disp (appdata v)
        {
            return v.vertex;
        }

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.normal = v.normal;
            o.uv = v.uv;
            return o;
        }

        #ifdef UNITY_CAN_COMPILE_TESSELLATION
            struct TessellationFactors
            {
                float edge[3] : SV_TessFactor;
                float inside : SV_InsideTessFactor;
            };

            struct HS_CONSTANT_OUTPUT
            {
                float edges[3] : SV_TessFactor;
                float inside : SV_InsideTessFactor;
            };

            HS_CONSTANT_OUTPUT hsConstant (InputPatch<appdata,3> v)
            {
                HS_CONSTANT_OUTPUT o;

                float4 p0 = UnityObjectToViewPos(v[0].vertex);
                float4 p1 = UnityObjectToViewPos(v[1].vertex);
                float4 p2 = UnityObjectToViewPos(v[2].vertex);

                float d0 = length(p0.xyz);
                float d1 = length(p1.xyz);
                float d2 = length(p2.xyz);

                float minDist = min(min(d0, d1), d2);
                float maxDist = max(max(d0, d1), d2);

                float dist = saturate((minDist - _MinDistance) / (_MaxDistance - _MinDistance));
                float factor = lerp(_Tessellation, 1, dist);

                o.edges[0] = factor;
                o.edges[1] = factor;
                o.edges[2] = factor;
                o.inside = factor;

                return o;
            }

            [domain("tri")]
            [partitioning("fractional_odd")]
            [outputtopology("triangle_cw")]
            [outputcontrolpoints(3)]
            [patchconstantfunc("hsConstant")]
            TessellationFactors hs (InputPatch<appdata,3> i, uint patchID : SV_PrimitiveID)
            {
                TessellationFactors o;
                o.edge[0] = 4;
                o.edge[1] = 4;
                o.edge[2] = 4;
                o.inside = 4;
                return o;
            }

            struct HS_OUTPUT
            {
                float4 vertex : SV_POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            [domain("tri")]
            DS_OUTPUT ds (TessellationFactors factors, OutputPatch<HS_OUTPUT,3> patch, float3 bary : SV_DomainLocation)
            {
                DS_OUTPUT o;

                float3 vertex =
                    patch[0].vertex * bary.x +
                    patch[1].vertex * bary.y +
                    patch[2].vertex * bary.z;

                float3 normal =
                    patch[0].normal * bary.x +
                    patch[1].normal * bary.y +
                    patch[2].normal * bary.z;

                float2 uv =
                    patch[0].uv * bary.x +
                    patch[1].uv * bary.y +
                    patch[2].uv * bary.z;

                o.vertex = vertex;
                o.normal = normal;
                o.uv = uv;

                return o;
            }
        #endif

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    Fallback "Standard"
}

// 3. Fur Shader
Shader "Custom/Fur"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _FurLength ("Fur Length", Range(0.1, 1)) = 0.5
        _FurDensity ("Fur Density", Range(0.01, 1)) = 0.3
        _FurTiling ("Fur Tiling", float) = 1.0
        _FurGravity ("Gravity Force", Range(0,1)) = 0.5
        _FurColor ("Fur Color", Color) = (1,1,1,1)
        _Layers ("Layer Count", Range(1, 100)) = 20
    }

    SubShader
    {
        Tags { "RenderType"="TransparentCutout" }
        LOD 200
        Cull Off

        CGPROGRAM
        #pragma surface surf Lambert vertex:vert alpha:fade
        #pragma shader_feature _FURSHADER_ON

        sampler2D _MainTex;
        fixed4 _Color;
        float _FurLength;
        float _FurDensity;
        float _FurTiling;
        float _FurGravity;
        fixed4 _FurColor;
        int _Layers;

        struct Input
        {
            float2 uv_MainTex;
            float furLayer;
        };

        void vert(inout appdata_full v, out Input o)
        {
            UNITY_INITIALIZE_OUTPUT(Input);
            o.uv_MainTex = v.texcoord;
            o.furLayer = v.color.r; // Pass layer from vertex color
        }

        void surf (Input IN, inout SurfaceOutput o)
        {
            float2 uv = IN.uv_MainTex * _FurTiling + float2(IN.furLayer * 0.2, IN.furLayer * 0.3);
            float4 fur = tex2D(_MainTex, uv);

            // Alpha based on fur density and layer
            float alpha = fur.r;
            alpha = smoothstep(_FurDensity * (1.0 - IN.furLayer), 1.0, alpha);

            // Fur color variation
            fixed4 furColor = lerp(_Color, _FurColor, IN.furLayer * 0.5);

            o.Albedo = furColor.rgb;
            o.Alpha = alpha * (1.0 - IN.furLayer);
        }
        ENDCG

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma shader_feature _FURSHADER_ON

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
                fixed4 color : COLOR;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
            };

            sampler2D _MainTex;
            float _FurLength;
            float _FurGravity;
            int _Layers;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.color = v.color;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float fur = tex2D(_MainTex, i.uv).r;
                float alpha = smoothstep(0.5, 1.0, fur);
                return fixed4(1, 1, 1, alpha);
            }
            ENDCG
        }
    }
}

// 4. Holographic Shader
Shader "Custom/Holographic"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _ScanLineSize ("Scan Line Size", Range(0.1, 10)) = 2.0
        _ScanLineSpeed ("Scan Line Speed", Range(-10, 10)) = 2.0
        _FlickerIntensity ("Flicker Intensity", Range(0, 1)) = 0.1
        _FlickerSpeed ("Flicker Speed", Range(1, 100)) = 50.0
        _GlowIntensity ("Glow Intensity", Range(0, 5)) = 2.0
    }

    SubShader
    {
        Tags {
            "Queue"="Transparent"
            "RenderType"="Transparent"
        }

        LOD 200
        Cull Off

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade
        #pragma shader_feature _HOLOGRAM_SHADER_ON

        sampler2D _MainTex;
        fixed4 _Color;
        float _ScanLineSize;
        float _ScanLineSpeed;
        float _FlickerIntensity;
        float _FlickerSpeed;
        float _GlowIntensity;

        struct Input
        {
            float2 uv_MainTex;
            float3 worldPos;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            // Base texture
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

            // Scan lines
            float scanline = sin(IN.worldPos.y * _ScanLineSize + _Time.y * _ScanLineSpeed) * 0.5 + 0.5;
            scanline = pow(scanline, 2.0);

            // Flicker effect
            float flicker = sin(_Time.y * _FlickerSpeed) * 0.5 + 0.5;
            flicker = lerp(1.0, flicker, _FlickerIntensity);

            // Edge glow
            float edge = 1.0 - saturate(dot(IN.worldPos - _WorldSpaceCameraPos, IN.worldPos - _WorldSpaceCameraPos));

            // Combine effects
            c.rgb = c.rgb * scanline * flicker + c.rgb * _GlowIntensity * edge;

            o.Albedo = c.rgb;
            o.Alpha = c.a * scanline * flicker;
            o.Emission = c.rgb * _GlowIntensity * edge;
        }
        ENDCG
    }
    Fallback "Transparent/VertexLit"
}

// 5. Particle Shader with Soft Particles
Shader "Custom/SoftParticles"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
        _Softness ("Softness", Range(0,1)) = 0.5
    }

    SubShader
    {
        Tags {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
        }

        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask RGB
        Cull Off Lighting Off ZWrite Off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_particles

            #include "UnityCG.cginc"

            sampler2D _MainTex;
            fixed4 _Color;
            float _InvFade;
            float _Softness;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                fixed4 color : COLOR;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
                #ifdef SOFTPARTICLES_ON
                    float4 projPos : TEXCOORD2;
                #endif
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.color = v.color;

                #ifdef SOFTPARTICLES_ON
                    o.projPos = ComputeScreenPos(o.vertex);
                    COMPUTE_EYEDEPTH(o.projPos);
                #endif

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                #ifdef SOFTPARTICLES_ON
                    float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, i.projPos));
                    float partZ = i.projPos.z;
                    float fade = saturate(_InvFade * (sceneZ - partZ));
                    fade = pow(fade, 1.0 + _Softness);
                    i.color.a *= fade;
                #endif

                fixed4 c = tex2D(_MainTex, i.uv) * i.color * _Color;
                return c;
            }
            ENDCG
        }
    }
}
CodeglslComplex

Post-Processing Shaders

Screen-space effects including bloom, depth of field, motion blur, and screen transitions

Difficulty

8/10

Estimated time

45 min

Tags

unity, shader, post processing, screen effects

Prerequisites

Expert shader programming, Render pipeline, Graphics math

glsl
// Unity Post-Processing Shaders

// 1. Bloom Effect Shader
Shader "Hidden/PostProcessing/Bloom"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Threshold ("Bloom Threshold", Range(0, 1)) = 0.5
        _Intensity ("Bloom Intensity", Range(0, 10)) = 1.0
        _BlurSize ("Blur Size", Range(1, 10)) = 3.0
        _Tint ("Bloom Tint", Color) = (1,1,1,1)
    }

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            float _Threshold;
            float _Intensity;
            int _BlurSize;
            fixed4 _Tint;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 original = tex2D(_MainTex, i.uv);

                // Apply threshold
                fixed luminance = dot(original.rgb, fixed3(0.2126, 0.7152, 0.0722);
                fixed4 bloom = luminance > _Threshold ? original : fixed4(0,0,0,1);

                // Apply intensity and tint
                bloom *= _Intensity * _Tint;

                return bloom;
            }
            ENDCG
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 texelSize = _MainTex_TexelSize.xy;
                float2 offset = texelSize * 2.0;

                fixed4 color = tex2D(_MainTex, i.uv);

                // Box blur
                for(int x = -2; x <= 2; x++)
                {
                    for(int y = -2; y <= 2; y++)
                    {
                        float2 offset = float2(x, y) * texelSize;
                        color += tex2D(_MainTex, i.uv + offset);
                    }
                }

                color /= 25.0; // Normalize by the number of samples

                return color;
            }
            ENDCG
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            sampler2D _BloomTex;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 original = tex2D(_MainTex, i.uv);
                fixed4 bloom = tex2D(_BloomTex, i.uv);

                return original + bloom;
            }
            ENDCG
        }
    }
}

// 2. Depth of Field Shader
Shader "Hidden/PostProcessing/DepthOfField"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _FocalDepth ("Focal Depth", Range(0, 1)) = 0.5
        _FocalRange ("Focal Range", Range(0, 1)) = 0.1
        _MaxBlurSize ("Max Blur Size", Range(0, 10)) = 5.0
        _Aperture ("Aperture", Range(0.1, 10)) = 2.8
    }

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            sampler2D _CameraDepthTexture;
            float4 _MainTex_TexelSize;
            float _FocalDepth;
            float _FocalRange;
            float _MaxBlurSize;
            float _Aperture;
            float4 _ProjectionParams;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float2 uvDepth : TEXCOORD1;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.uvDepth = ComputeScreenPos(o.vertex).xy / ComputeScreenPos(o.vertex).w;
                return o;
            }

            float LinearEyeDepth(float z)
            {
                return -Linear01Depth(z) * _ProjectionParams.z;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // Get scene depth
                float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uvDepth);
                float sceneDepth = LinearEyeDepth(depth);
                float focalPlane = _FocalDepth * _ProjectionParams.z;

                // Calculate circle of confusion
                float coc = abs(sceneDepth - focalPlane) / _FocalRange * _Aperture;
                coc = saturate(coc);

                // Apply blur based on CoC
                float blurSize = coc * _MaxBlurSize;

                fixed4 color = tex2D(_MainTex, i.uv);

                if(blurSize > 1.0)
                {
                    // Box blur
                    float2 texelSize = _MainTex_TexelSize.xy;
                    int blurRadius = (int)blurSize;

                    fixed4 blurredColor = fixed4(0,0,0,0);
                    int sampleCount = 0;

                    for(int x = -blurRadius; x <= blurRadius; x++)
                    {
                        for(int y = -blurRadius; y <= blurRadius; y++)
                        {
                            if(x*x + y*y <= blurRadius * blurRadius)
                            {
                                float2 offset = float2(x, y) * texelSize;
                                blurredColor += tex2D(_MainTex, i.uv + offset);
                                sampleCount++;
                            }
                        }
                    }

                    blurredColor /= sampleCount;

                    // Blend based on CoC
                    color = lerp(color, blurredColor, coc);
                }

                return color;
            }
            ENDCG
        }
    }
}

// 3. Motion Blur Shader
Shader "Hidden/PostProcessing/MotionBlur"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _VelocityScale ("Velocity Scale", Range(0, 2)) = 1.0
        _MaxVelocity ("Max Velocity", Range(0, 10)) = 5.0
        _NumSamples ("Number of Samples", Range(4, 32)) = 16
    }

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            sampler2D _VelocityTex;
            float2 _MainTex_TexelSize;
            float _VelocityScale;
            float _MaxVelocity;
            int _NumSamples;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // Get velocity vector
                float2 velocity = tex2D(_VelocityTex, i.uv).rg * 2.0 - 1.0;
                velocity *= _VelocityScale;

                // Limit velocity
                float velocityLength = length(velocity);
                if(velocityLength > _MaxVelocity)
                {
                    velocity = normalize(velocity) * _MaxVelocity;
                }

                // Motion blur
                float2 texelSize = _MainTex_TexelSize.xy;
                fixed4 blurredColor = fixed4(0,0,0,0);
                float totalWeight = 0.0;

                for(int j = 0; j < _NumSamples; j++)
                {
                    float t = (float)j / (_NumSamples - 1) - 0.5;
                    float2 sampleUV = i.uv + velocity * texelSize * t;

                    // Weight based on distance from center
                    float weight = 1.0 - abs(t);
                    blurredColor += tex2D(_MainTex, sampleUV) * weight;
                    totalWeight += weight;
                }

                blurredColor /= totalWeight;

                return blurredColor;
            }
            ENDCG
        }
    }
}

// 4. Screen Transition Shader
Shader "Hidden/PostProcessing/ScreenTransition"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _TransitionTex ("Transition Texture", 2D) = "white" {}
        _NextTex ("Next Texture", 2D) = "white" {}
        _Progress ("Transition Progress", Range(0, 1)) = 0.0
        _TransitionType ("Transition Type", Range(0, 4)) = 0
        _EdgeWidth ("Edge Width", Range(0, 0.5)) = 0.1
        _EdgeSoftness ("Edge Softness", Range(0, 0.5)) = 0.05
    }

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            sampler2D _TransitionTex;
            sampler2D _NextTex;
            float _Progress;
            int _TransitionType;
            float _EdgeWidth;
            float _EdgeSoftness;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            float FadeTransition(float progress)
            {
                return progress;
            }

            float WipeTransition(float2 uv, float progress)
            {
                return progress > uv.x ? 1.0 : 0.0;
            }

            float CircleTransition(float2 uv, float progress)
            {
                float2 center = float2(0.5, 0.5);
                float distance = length(uv - center);
                return distance > (1.0 - progress) ? 1.0 : 0.0;
            }

            float DiagonalWipeTransition(float2 uv, float progress)
            {
                float2 diagonal = float2(1.0, 1.0);
                float diagonalPos = dot(uv, normalize(diagonal));
                return diagonalPos > progress ? 1.0 : 0.0;
            }

            float RandomTransition(float2 uv, float progress)
            {
                float noise = tex2D(_TransitionTex, uv).r;
                return noise > progress ? 1.0 : 0.0;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float transitionValue = 0.0;

                switch(_TransitionType)
                {
                    case 0: // Fade
                        transitionValue = FadeTransition(_Progress);
                        break;
                    case 1: // Wipe
                        transitionValue = WipeTransition(i.uv, _Progress);
                        break;
                    case 2: // Circle
                        transitionValue = CircleTransition(i.uv, _Progress);
                        break;
                    case 3: // Diagonal Wipe
                        transitionValue = DiagonalWipeTransition(i.uv, _Progress);
                        break;
                    case 4: // Random Noise
                        transitionValue = RandomTransition(i.uv, _Progress);
                        break;
                }

                // Edge smoothing
                float edge = smoothstep(_Progress - _EdgeSoftness, _Progress + _EdgeSoftness, transitionValue);
                edge = smoothstep(_Progress - _EdgeWidth - _EdgeSoftness,
                                 _Progress - _EdgeWidth + _EdgeSoftness, edge);

                fixed4 currentColor = tex2D(_MainTex, i.uv);
                fixed4 nextColor = tex2D(_NextTex, i.uv);

                // Blend between scenes
                fixed4 finalColor = lerp(nextColor, currentColor, edge);

                return finalColor;
            }
            ENDCG
        }
    }
}

// 5. Vignette Effect Shader
Shader "Hidden/PostProcessing/Vignette"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _VignetteIntensity ("Vignette Intensity", Range(0, 2)) = 1.0
        _VignetteRadius ("Vignette Radius", Range(0, 2)) = 0.8
        _VignetteSmoothness ("Vignette Smoothness", Range(0, 1)) = 0.1
        _VignetteColor ("Vignette Color", Color) = (0,0,0,1)
    }

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float _VignetteIntensity;
            float _VignetteRadius;
            float _VignetteSmoothness;
            fixed4 _VignetteColor;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 originalColor = tex2D(_MainTex, i.uv);

                // Calculate vignette
                float2 center = float2(0.5, 0.5);
                float dist = distance(i.uv, center);

                float vignette = 1.0 - smoothstep(_VignetteRadius, _VignetteRadius + _VignetteSmoothness, dist);
                vignette = saturate(vignette * _VignetteIntensity);

                // Apply vignette
                fixed3 vignetteColor = lerp(_VignetteColor.rgb, originalColor.rgb, vignette);

                return fixed4(vignetteColor, originalColor.a);
            }
            ENDCG
        }
    }
}

Tools

Tools frequently paired with this sample

Related

Related sample collections

Tool usage guide

Sample-focused context for search and workflow understanding

Title

Unity Shader Samples

Description

Unity HLSL shader examples including surface shaders, vertex/fragment shaders, and post-processing effects

Overview

Unity HLSL shader examples including surface shaders, vertex/fragment shaders, and post-processing effects

When to use

  • Use this sample set when you want reference inputs for Unity Shader Samples.
  • Use it to preview output formats and compare related sample variants.

How it works

  1. 1Open a sample entry to inspect the prepared example payload or asset.
  2. 2Compare it with related tools to understand how the workflow connects.

Use cases

  • Basic Unity Shaders
  • Advanced Unity Shaders
  • Post-Processing Shaders

FAQ

What is included in Unity Shader Samples?

This page includes curated sample entries, related tools, and neighboring sample collections for Unity Shader Samples.

Home
Tools3197
Samples593
Visualizations461
Viewers103
Hubs229
Tags333
Images, Audio & Video655

Image, audio, and video processing, conversion, and optimization tools

Math, Date & Finance644

Calculators, numerics, date logic, statistics, and finance tools

Design & Color296

Color, layout, graphics, visual styling, and design helper tools

Text & Writing209

Writing, cleanup, formatting, extraction, and text analysis tools

Developer & Web193

Developer utilities, networking, web debugging, and automation helpers

Conversion & Encoding175

Format, file, archive, unit, and encoding conversion tools

UI Screenshot Structure Review and Development Handoff
Piano Sketch Creation, MIDI Review and Listening Demo Handoff
Retro Game Texture Review and Asset Handoff
Screenshot-Based Procedure Guide Review and Handoff
Responsive Page Change Review and Evidence Handoff

© 2026 Elysia Tools. All rights reserved.

DocsPricingAboutTerms of ServicePrivacy PolicyCookiesContact

Development

HTML Tags Reference

Complete reference guide for all standard HTML5 tags with categories and descriptions

AI Tools

AI Face Age & Gender

Estimate age and gender for each detected face

AI Tools

AI Face Compare (1:1)

Compare two images, output embedding distance and match boolean by threshold, only compare the first face in each image

AI Tools

AI Face Detection

Detect faces in an image and return bounding box coordinates

AI Tools

AI Face Expressions

Classify facial expressions per face (neutral/happy/sad/angry/fearful/disgusted/surprised)

AI Tools

AI Face Landmarks

Detect facial landmarks (68 points) and return coordinates for each face

Development

API Breaking Changes Detector & Migration Planner

Compare two OpenAPI 3.x schemas, identify breaking changes, grade client impact, and suggest migration or compatibility strategies

Development

Array Grouper

Group array elements based on various criteria such as length, alphabetical order, numeric ranges, custom conditions, and more

Game Development

Unity C# Script Samples

Unity C# scripting examples covering player movement, UI systems, physics, animations, and game mechanics

Game Development

Bevy Game Engine Samples

Bevy Rust game engine examples with ECS, 2D/3D graphics, audio, and game mechanics implementations

Game Development

Phaser.js Samples

Phaser.js game engine examples including 2D games, animations, physics, sprites, and interactive gameplay mechanics