Ball Of Fire

This shader is converted from shadertoy: Ball Of Fire (shadertoy.com)

Added uniform parameter for time, so you can change it form gdscript and make animation.

Shader code
shader_type canvas_item;

uniform float time : hint_range(0.0, 10.0);

float snoise(vec3 uv, float res)
{
    const vec3 s = vec3(1e0, 1e2, 1e3);
    uv *= res;
    
    vec3 uv0 = floor(mod(uv, res)) * s;
    vec3 uv1 = floor(mod(uv + vec3(1.0), res)) * s;
    
    vec3 f = fract(uv);
    f = f * f * (3.0 - 2.0 * f);

    vec4 v = vec4(uv0.x + uv0.y + uv0.z, uv1.x + uv0.y + uv0.z,
                  uv0.x + uv1.y + uv0.z, uv1.x + uv1.y + uv0.z);

    vec4 r = fract(sin(v * 1e-1) * 1e3);
    float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);

    r = fract(sin((v + uv1.z - uv0.z) * 1e-1) * 1e3);
    float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
    
    return mix(r0, r1, f.z) * 2.0 - 1.0;
}

void fragment() 
{
    // Calcular las coordenadas de la pantalla usando SCREEN_PIXEL_SIZE
    vec2 screen_size = vec2(1.0 / SCREEN_PIXEL_SIZE.x, 1.0 / SCREEN_PIXEL_SIZE.y);
    vec2 fragCoord = FRAGCOORD.xy;
    
    vec2 p = -0.5 + fragCoord.xy / screen_size;
    p.x *= screen_size.x / screen_size.y;
    
    float color = 3.0 - (3.0 * length(2.0 * p));
    
    vec3 coord = vec3(atan(p.x, p.y) / 6.2832 + 0.5, length(p) * 0.4, 0.5);
    
    // if you dont want use gdscript to animate you can replace the 'time' to 'TIME'
    for (int i = 1; i <= 7; i++) 
    {
        float power = pow(2.0, float(i));
        color += (1.5 / power) * snoise(coord + vec3(0.0, -time * 0.05, time * 0.01), power * 16.0);
    }
    
    COLOR = vec4(color, pow(max(color, 0.0), 2.0) * 0.4, pow(max(color, 0.0), 3.0) * 0.15, 1.0);
}
Live Preview
Tags
animation, Godot4.3, perlin
This shader is a port from an existing Shadertoy project. Shadertoy shaders are by default protected under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) license unless anything else has been stated by the author. For more info, see our License terms.

More from ahaugas

Related shaders

guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Gerardo LCDF
1 month ago

I updated the code to run in a continuous loop, with a speed parameter to control the rate of playback

shader_type canvas_item;


uniform float speed : hint_range(0.0, 5.0) = 1.0;


float snoise(vec3 uv, float res)
{
    const vec3 s = vec3(1e0, 1e2, 1e3);
    uv *= res;
    
    vec3 uv0 = floor(mod(uv, res)) * s;
    vec3 uv1 = floor(mod(uv + vec3(1.0), res)) * s;
    
    vec3 f = fract(uv);
    f = f * f * (3.0 - 2.0 * f);


    vec4 v = vec4(uv0.x + uv0.y + uv0.z, uv1.x + uv0.y + uv0.z,
                  uv0.x + uv1.y + uv0.z, uv1.x + uv1.y + uv0.z);


    vec4 r = fract(sin(v * 1e-1) * 1e3);
    float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);


    r = fract(sin((v + uv1.z - uv0.z) * 1e-1) * 1e3);
    float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
    
    return mix(r0, r1, f.z) * 2.0 - 1.0;
}


void fragment() 
{
    float current_time = TIME * speed;
    
    vec2 screen_size = vec2(1.0 / SCREEN_PIXEL_SIZE.x, 1.0 / SCREEN_PIXEL_SIZE.y);
    vec2 fragCoord = FRAGCOORD.xy;
    
    vec2 p = -0.5 + fragCoord.xy / screen_size;
    p.x *= screen_size.x / screen_size.y;
    
    float color = 3.0 - (3.0 * length(2.0 * p));
    
    vec3 coord = vec3(atan(p.x, p.y) / 6.2832 + 0.5, length(p) * 0.4, 0.5);
    
    for (int i = 1; i <= 7; i++) 
    {
        float power = pow(2.0, float(i));
        color += (1.5 / power) * snoise(coord + vec3(0.0, -current_time * 0.05, current_time * 0.01), power * 16.0);
    }
    
    COLOR = vec4(color, pow(max(color, 0.0), 2.0) * 0.4, pow(max(color, 0.0), 3.0) * 0.15, 1.0);
}