Fire Shader
Here's how to create a Fire Shader. The effect works by scrolling a noise texture over time and using it to mask a gradient texture, giving the illusion of flickering flames. As always, you can also find below the HLSL Shader and, if you're supporting me on Patreon, the download link for the Unity Package.
How it works
The shader samples 2 textures: a noise texture (scrolled upward by subtracting _Time.x from the UV's Y) and a gradient texture (static). Three step() calls compare the noise value against the gradient value at offsets of 0, -0.2, and -0.4. Those 3 thresholds define 3 "layers" of fire (L1, L2, L3 in the shader). The outer layer controls alpha, and the 2 inner layers control the color blend between the brighter and darker fire colors. No vertex distortion is used, which keeps the shader very cheap - just 2 texture samples and a handful of math ops per pixel.
HLSL
The shader is transparent, so the SubShader uses Blend SrcAlpha OneMinusSrcAlpha. It requires 2 textures as inputs: a tileable noise and a gradient that shapes the fire outline. The scroll speed is controlled by _Time.x (which is _Time.y / 20), so you can speed it up by multiplying it.
- Sample the noise texture with scrolling UVs:
IN.uv - float2(0, _Time.x). - Sample the gradient texture with the original UVs.
- Run 3 step calls at offsets 0, -0.2, and -0.4 to get 3 fire layer masks.
- Set alpha to
step1(the outermost layer). - Lerp between
_BrighterColand_DarkerColusingstep1 - step2, then blend in_MiddleColusingstep2 - step3.
//@febucci, https://www.febucci.com/tutorials/
//Support my work here: https://www.patreon.com/febucci
Shader "Fire"
{
Properties
{
_NoiseTex("Noise Texture", 2D) = "white" {}
_GradientTex("Gradient Texture", 2D) = "white" {}
_BrighterCol("Brighter Color", Color) = (1,1,1,1)
_MiddleCol("Middle Color", Color) = (.7,.7,.7,1)
_DarkerCol("Darker Color", Color) = (.4,.4,.4,1)
}
SubShader
{
//The shader is transparent
Tags
{
"RenderType" = "Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityShaderVariables.cginc" //to use _Time
sampler2D _NoiseTex;
sampler2D _GradientTex;
float4 _BrighterCol;
float4 _MiddleCol;
float4 _DarkerCol;
//Input for the vertex
struct appdata {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
//Output for the fragment
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy;
return o;
}
float4 frag(v2f IN) : SV_Target {
float noiseValue = tex2D(_NoiseTex, IN.uv - float2(0, _Time.x)).x; //fire with scrolling
float gradientValue = tex2D(_GradientTex, IN.uv).x;
float step1 = step(noiseValue, gradientValue);
float step2 = step(noiseValue, gradientValue-0.2);
float step3 = step(noiseValue, gradientValue-0.4);
//The entire fire color
float4 c = float4
(
//Calculates where to place the darker color instead of the brighter one
lerp
(
_BrighterCol.rgb,
_DarkerCol.rgb,
step1 - step2 //Corresponds to "L1" in my GIF
),
step1 //This is the alpha of our fire, which is the "outer" color, i.e. the step1
);
c.rgb = lerp //Calculates where to place the middle color
(
c.rgb,
_MiddleCol.rgb,
step2 - step3 //Corresponds to "L2" in my GIF
);
return c;
}
ENDCG
}
}
}
Amplify Shader

Frequently asked questions
What textures do I need?
You need 2: a tileable noise texture (any grayscale noise works) and a gradient texture that shapes the fire's silhouette, typically brighter at the base and darker at the top.
How do I change the scroll speed?
Multiply _Time.x by a value greater than 1 to speed it up, or less than 1 to slow it down. You can expose it as a shader property if you want to control it at runtime.
Can I add a fourth color layer?
Yes, add another step call at an additional offset (e.g., -0.6) and blend in a fourth color the same way step3 handles the middle color.
Does this work in the Universal Render Pipeline?
The HLSL version uses Unity's built-in CG includes, so it only works in the Built-in Render Pipeline. For URP you'll need to rewrite it as an HLSL shader or recreate it in Shader Graph.
Comments