How to create fire effect using shader graph in Unity

You would probably have heard the advice "Never play with the fire". Well today we are going to play with it in unity.

I am using unity version 2022.2 but it will work on any Unity LTS version. Setup a project in URP. 

Let's create a lit shader graph. Call it FireShaderGraph. First let's configure our graph settings a bit, 

  • let's check "Allow material override" which will allow us to modify "Surface Options" values from the inspector.
  • Select surface type transparent, blending mode "Additive". 
  • Also check "Alpha clipping".
  • Uncheck "Cast shadows" we don't want our mesh to cast shadow and also uncheck "Receive Shadows".
and that's it for our graph settings. It will look something like this.

Now we need a texture for our fire so let's quickly create a property for a texture in our black board. Call it main texture, in node settings let's give it a default texture. 

I have created following texture in GIMP with soft brush and smudge tool, but you can create your own, just notice how I left plenty of space from the edges, that's important. Make sure you do the same.

Drag it in. sample it with sample texture 2d node. 

Now let's also create another property for color, call it base color. Set mode HDR, and give a default orange ish color. Drag that in, multiply with our texture and hook it to our "Emission" because fire basically emits color.



Now Let's also take our sampled texture output and feed it in "Alpha".

The "Alpha Clip Threshold" what it does is, assume if it has current value of 0.5 so it is telling unity that if a pixel is 50% or less opaque, do not render it.

I want to access it from Inspector so let's create a property, call it "clipThreshold", give a default of 0.02 set mode slider from 0 to 1. Drag that in and feed it here.




We want to distort this texture procedurally so let's add "Simple noise", We also want to adjust its scale from the inspector so let's create another float property, call it "distortionScale", give a default value of 10, drag it in and hook it to the scale.

Now We want to scroll this noise, and to do that we need "Tiling and offset" node, feed its output to the "UV". and to scroll this vertically we need to change the offset value of Y.

We want to change it over time so let's create "Time" node, Grab the output of time and to control the speed multiply with the float and to control the speed from Inspector, you guessed it, let's create a float property and call it "Speed", give default value of something like 0.5, drag that in and multiply with time.

Offset accepts Vector2 but we only have a float value so lets create a "Vector2" node, feed the multiply output to the Y and pass this into our offset, our noise will start scrolling in Y axis and graph will look something like this.




Here we have a minor issue that our noise is scrolling in downwards direction.

We can simply set the speed in negative value to fix this but We want to invert it in shader itself so the positive speed scrolls upward and negative scrolls downward.

To do just that take the output of our speed, feed it into "Negate" node then pass its output to "Multiply" node.



Okay so our goal it to distort the texture's uv with our scrolling noise, and to do that let's create another "Tiling and offset" node.

To mix this, we have a handy little node called "Blend" node, feed our uv into "base", our noise into "blend" and the "opacity" determines how much we want to mix the above values. It also has different modes but "overlay" works the best in our case. let's grab the output and feed it into "UV".




Now we have a fire-y looking texture, which we can adjust it with this "opacity" value. But to make it more natural let's grab "Sine Time" from our "Time" node.

Sine time basically gives value from -1 to 1 overtime and feed it into "Remap" node. It will as the name implies remap those values. So here we are telling remap node that we want to remap the input, which has the original range of values from -1 to 1 (In Min Max). and We need to remap them to something like 0.4 to 0.8 (Out Min Max). Type in a valid range that works for you and feed it into opacity.

That is pretty much our shader, the entire shader will look something like this.



Trouble following along? Check out this video.


Thank you so much for reading.

Comments