Radial Fire 2D

This is arlez80 fire2d shader (https://bitbucket.org/arlez80/fire-godot4/src/master/fire2d.gdshader) but radial.

How to use?

  • The default parameters works just fine.
  • Set the noise texture to seamless AND VERY IMPORTANT: Noise height must be greater than width. In the example image the values are 128 and 1024. If you don’t want to use a large texture, you can simply multiply the noise_texture UV.y, or something, but I get better results with a large noise texture.
  • Set the texture to seamless (0.25) to avoide circular pattern lines.
  • When poster_color is set to less than at least 1 color, there is no posterization at all. 
Shader code
/*
	炎シェーダー by あるる(きのもと 結衣)
	Fire Shader by Yui Kinomoto @arlez80

	MIT License
*/
shader_type canvas_item;
render_mode unshaded;

//Noise and color uniforms
uniform sampler2D	noise_tex			: hint_default_white, repeat_enable;
uniform vec4		root_color			: source_color = vec4(1.0, 0.75, 0.3, 1.0);
uniform vec4		tip_color			: source_color = vec4(1.0, 0.03, 0.001, 1.0);
uniform float		poster_color		: hint_range(0.0, 16.0) = 6.0;
//Fire stuff
uniform float		fire_alpha			: hint_range(0.0, 1.0) = 1.0;
uniform vec2		fire_speed			= vec2(0.015, 0.5);
uniform float		fire_aperture		: hint_range(0.0, 5.0) = 0.22;
//Vignette
uniform float		vignette_radius		: hint_range(0.0, 1.0) = 0.25; //fade start
uniform float		vignette_falloff	: hint_range(0.0, 0.5) = 0.25; //fade width
uniform float		noise_influence		: hint_range(0.0, 1.0) = 1.00; //noise influence

vec2 polar_coordinates(vec2 uv, vec2 center, float zoom, float repeat) {
    vec2 d = uv - center;
    float r     = length(d) * 2.0;
    float theta = atan(d.y, d.x) * (1.0 / (2.0 * 3.1416));
    return mod(vec2(r * zoom, theta * repeat), 1.0);
}

void fragment() {
	vec2  center = vec2(0.5);
	vec2  p = polar_coordinates(UV, center, 1.0, 1.0);

	//fire "movement"
	p.x += TIME * fire_speed.y;
	p.y += sin(TIME) * fire_speed.x; //-> X is rotation!

	//noise texture
	//float n = texture(noise_tex, vec2(p.x , p.y * PI)).r; //alternative to a large noise texture!
	float n = texture(noise_tex, p).r;

	//the fire itslef
	float dist = distance(UV, center);
	float edge = clamp(1.0 - dist, 0.0, 1.0);
	float noise_val = edge * (((edge + fire_aperture) * n - fire_aperture) * 75.0);
	noise_val = clamp(noise_val, 0.0, 1.0);

	//vignette
	float effective_radius = vignette_radius + n * noise_influence * vignette_falloff;
	float mask = smoothstep(effective_radius + vignette_falloff, effective_radius, 1.0-dist);

	//final alpha
	float alpha = noise_val * fire_alpha * mask;
	
	//color posterization
	vec4 fire_color;
	if (poster_color >= 1.0){
		float quantized = floor(n * poster_color) / poster_color;
		fire_color = mix(tip_color, root_color, quantized);
		alpha = floor(alpha * poster_color) / poster_color;
	}
	else{
		fire_color = mix(tip_color, root_color, n);
	}
	
	COLOR = vec4(fire_color.rgb, alpha);
}
Live Preview
Tags
circular, fire, flame, radial
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from ColorauGuiyino

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments