2D Candle/Torch Fire

Alternate version of the 2D fire shader by godotshaders

Creates a 2-tone fireball with an egg shape, like a candle or torch flame. 

Usage

Apply to a `TextureRect`, `ColorRect`, `Sprite2D`, or similar.

Set the inner and outer colors of the flame. An egg shaped object should take shape. Adjust the thresholds of each layer, if desired.

Set the soft edge to the desired amount of bluring between colors. I use values in the range of 0.01 – 0.08.

Add a NoiseTexture2D to the Noise Texture shader parameter. Set Seamless to true and set Noise to FastNoiseLite. Tweak the width and height of the texture along with the frequency of the noise until your find a value that works. For example, for a small ball of fire, I used 64×64 with a frequency of 0.025.

Multiplier adjusts the strength of the fire. Stretch adjusts the overall size of the flame and noise.

Shader code
/* 
Original shader from Fubucci – https://www.febucci.com/2019/05/fire-shader/ 
Converted to Godot Shader Language by Godot Shaders - godotshaders.com/shader/2D-fire/
Updated by Maaack
*/
shader_type canvas_item;

uniform vec4 inner_color : source_color;
uniform vec4 outer_color : source_color;
uniform float inner_threshold = 0.36;
uniform float outer_threshold = 0.1;
uniform float soft_edge = 0.0;
uniform float fire_radius = 0.4;
uniform sampler2D noise_texture : repeat_enable;
uniform float multiplier = 1.0;
uniform vec2 stretch = vec2(1.0, 1.0);

uniform vec2 center = vec2(0.5, 0.8);

const vec4 transparent = vec4(1.0, 1.0, 1.0, 0.0);

float egg_shape(vec2 coord, float radius){
	vec2 diff = abs(coord - center);

	if (coord.y < center.y){
		diff.y /= 2.0;
	} else {
		diff.y *= 2.0;
	}

	float dist = sqrt(diff.x * diff.x + diff.y * diff.y) / radius;
	float value = sqrt(1.0 - dist * dist);
	return clamp(value, 0.0, 1.0);
}

float get_fire_shape(vec2 coord, float radius){
	float fire_s = egg_shape(coord, radius*0.5) * 0.75;
	fire_s += egg_shape(coord, radius*0.75) * 0.5;
	fire_s += egg_shape(coord, radius) * 0.25;
	return fire_s;
}
void fragment() {
	vec4 sum_color;
	float mod_time = mod(TIME, 600.0);
	vec2 coord = UV / stretch;
	float noise_value = texture(noise_texture, coord + vec2(0, mod_time)).x;
	float course_noise_value = texture(noise_texture, coord + vec2(0, mod_time) / 2.0).x;
	float shape_value = get_fire_shape(coord, fire_radius);

	float combined = course_noise_value * noise_value * shape_value * multiplier;

	float outer_soft_edge_step = step(outer_threshold - soft_edge, combined);
	float outer_step = step(outer_threshold, combined);
	float inner_soft_edge_step = step(inner_threshold - soft_edge, combined);
	float inner_step = step(inner_threshold, combined);
	float outer_soft_edge_ratio = (combined - (outer_threshold - soft_edge)) / max(soft_edge, 0.0001);
	float inner_soft_edge_ratio = (combined - (inner_threshold - soft_edge)) / max(soft_edge, 0.0001);

	sum_color = transparent;
	sum_color = mix(sum_color, outer_color, outer_soft_edge_step * outer_soft_edge_ratio);
	sum_color = mix(sum_color, outer_color, outer_step);
	sum_color = mix(sum_color, inner_color, inner_soft_edge_step * inner_soft_edge_ratio);
	sum_color = mix(sum_color, inner_color, inner_step);
	
	COLOR = sum_color;
}
Live Preview
Tags
candle, cartoon, fire, flame, torch
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from Maaack

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments