Fire (Anime Style)

Shader code
shader_type canvas_item;

// Texturas
uniform sampler2D noise_tex : repeat_enable;
uniform sampler2D noise_tex2 : repeat_enable;
uniform sampler2D formato_custom_tex : source_color; 

// ==========================================
// 📦 LIMITES E ESPAÇO
// ==========================================
uniform float margem_seguranca : hint_range(0.0, 0.5) = 0.2; 

// ==========================================
// 🎨 CORES E ESTILO
// ==========================================
uniform bool modo_rgb = false;
uniform vec4 cor_contorno : source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4 cor_externa : source_color = vec4(0.8, 0.15, 0.0, 1.0);
uniform vec4 cor_media : source_color = vec4(1.0, 0.5, 0.0, 1.0);
uniform vec4 cor_nucleo : source_color = vec4(1.0, 0.9, 0.2, 1.0);

uniform bool outline_interno_ativo = true;
uniform float outline_interno_chance : hint_range(0.0, 1.0) = 0.3;
uniform float outline_interno_velocidade : hint_range(1.0, 20.0) = 10.0;

// ==========================================
// 🎭 FORMA E MÁSCARAS (Ajustado)
// ==========================================
uniform bool usar_rastro_procedural = true; 
uniform float angulo_arco : hint_range(0.0, 360.0) = 180.0;
uniform float espessura_rastro : hint_range(0.0, 0.5) = 0.2;
uniform float suavizacao_borda : hint_range(0.01, 0.5) = 0.1;

uniform bool usar_textura_formato = false;
uniform vec2 formato_tex_escala = vec2(1.0, 1.0); // Escolher tamanho da textura
uniform float mistura_textura_procedural : hint_range(0.0, 1.0) = 0.5;

uniform bool distorcer_textura = true;
uniform float distorcao_forca : hint_range(0.0, 0.5) = 0.05;
uniform float distorcao_velocidade : hint_range(0.1, 10.0) = 2.0;
uniform float distorcao_escala : hint_range(0.1, 10.0) = 3.0;

// ==========================================
// 👻 TRANSPARÊNCIA E EFEITOS
// ==========================================
uniform float alpha_geral : hint_range(0.0, 1.0) = 1.0;
uniform bool radomizar_alpha = false;
uniform float alpha_min : hint_range(0.0, 1.0) = 0.4;
uniform float alpha_max : hint_range(0.0, 1.0) = 1.0;
uniform float vel_radomizacao : hint_range(1.0, 30.0) = 15.0;

uniform bool pixelado = true;
uniform float qtd_pixels : hint_range(16.0, 256.0) = 64.0;
uniform float intensidade_glow : hint_range(1.0, 5.0) = 1.5;

// ==========================================
// 🌪️ VENTO E FAÍSCAS DINÂMICAS
// ==========================================
uniform vec2 direcao_vento = vec2(0.0, -1.0);
uniform float forca_fogo : hint_range(0.1, 5.0) = 1.5;
uniform float variacao_caos : hint_range(0.1, 3.0) = 1.0;

uniform bool criar_faiscas = true;
uniform float qtd_faiscas : hint_range(0.1, 1.0) = 0.5;
uniform float velocidade_puxao_faiscas : hint_range(0.1, 5.0) = 2.0;
uniform bool faiscas_com_borda = true;

// Tempos de Spawn/Blink
uniform bool faisca_tempo_radomico = true;
uniform float faisca_tempo_min : hint_range(0.1, 5.0) = 0.5;
uniform float faisca_tempo_max : hint_range(1.0, 10.0) = 3.0;

// Tamanhos
uniform float faisca_tamanho_base : hint_range(0.5, 15.0) = 8.0;
uniform bool faisca_tamanho_radomico = true;
uniform float faisca_tamanho_min : hint_range(0.1, 5.0) = 0.5;
uniform float faisca_tamanho_max : hint_range(1.0, 10.0) = 2.0;

vec3 hsv2rgb(vec3 c) {
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void fragment() {
    vec2 uv = UV;
    if (pixelado) uv = floor(uv * qtd_pixels) / qtd_pixels;

    // 1. Margem de Segurança
    vec2 uv_segura = (uv - 0.5) * (1.0 + margem_seguranca * 2.0) + 0.5;
    float bounds_mask = step(0.0, uv_segura.x) * step(uv_segura.x, 1.0) * step(0.0, uv_segura.y) * step(uv_segura.y, 1.0);

    // 2. Distorção
    vec2 uv_textura = uv_segura;
    if (distorcer_textura) {
        vec2 noise_desloc = texture(noise_tex, uv_segura * distorcao_escala + TIME * distorcao_velocidade).rg;
        uv_textura += (noise_desloc - 0.5) * distorcao_forca;
    }

    // 3. Máscaras de Formato
    float mask_proc = 0.0;
    float mask_faisca_area = 0.0;
    if (usar_rastro_procedural) {
        vec2 p = uv_segura - 0.5;
        float d = length(p);
        float a = degrees(atan(p.y, p.x)) + 180.0;
        float m_a = smoothstep(angulo_arco / 2.0 + suavizacao_borda * 10.0, angulo_arco / 2.0, abs(a - 180.0));
        float m_d = smoothstep(espessura_rastro + suavizacao_borda, espessura_rastro, abs(d - 0.3));
        mask_proc = m_a * m_d;
        mask_faisca_area = m_a * smoothstep(espessura_rastro + margem_seguranca, espessura_rastro, abs(d - 0.3));
    }

    float mask_tex = 0.0;
    if (usar_textura_formato) {
        vec2 uv_t = (uv_textura - 0.5) / formato_tex_escala + 0.5;
        mask_tex = texture(formato_custom_tex, uv_t).a;
        mask_tex *= step(0.0, uv_t.x) * step(uv_t.x, 1.0) * step(0.0, uv_t.y) * step(uv_t.y, 1.0);
    }

    float mask_final = 0.0;
    if (usar_rastro_procedural && usar_textura_formato) mask_final = mix(mask_proc, mask_tex, mistura_textura_procedural);
    else if (usar_rastro_procedural) mask_final = mask_proc;
    else if (usar_textura_formato) mask_final = mask_tex;
    else mask_final = 1.0;

    // 4. Ruído do Fogo
    vec2 scroll1 = TIME * direcao_vento * forca_fogo;
    vec2 scroll2 = TIME * direcao_vento * (forca_fogo * 1.2) + vec2(TIME * 0.1, 0.0);
    float n1 = texture(noise_tex, uv_segura * variacao_caos + scroll1).r;
    float n2 = texture(noise_tex2, uv_segura * (variacao_caos * 1.5) + scroll2).r;
    float fire_logic = (n1 * 0.6 + n2 * 0.4) * mask_final;

    // 5. Cores e Outlines
    vec4 col = vec4(0.0);
    float alpha = 0.0;
    vec4 c_core = cor_nucleo; vec4 c_mid = cor_media; vec4 c_outer = cor_externa;

    if (modo_rgb) {
        c_core.rgb = hsv2rgb(vec3(TIME * 0.5, 0.8, 1.0));
        c_mid.rgb = hsv2rgb(vec3(TIME * 0.5 - 0.1, 0.9, 0.8));
        c_outer.rgb = hsv2rgb(vec3(TIME * 0.5 - 0.2, 1.0, 0.6));
    }

    if (fire_logic > 0.55) { col = c_core; alpha = 1.0; }
    else if (fire_logic > 0.35) { col = c_mid; alpha = 1.0; }
    else if (fire_logic > 0.15) { col = c_outer; alpha = 1.0; }
    else if (fire_logic > 0.05) { col = cor_contorno; alpha = 1.0; }

    // Outline Interno
    if (outline_interno_ativo && fire_logic > 0.15) {
        float db1 = abs(fire_logic - 0.55); float db2 = abs(fire_logic - 0.35);
        if (db1 < 0.03 || db2 < 0.03) {
            float ch = texture(noise_tex2, uv_segura * 5.0 + vec2(TIME * outline_interno_velocidade)).r;
            if (ch < outline_interno_chance) col = cor_contorno;
        }
    }

    // 6. Faíscas
    if (criar_faiscas && fire_logic <= 0.05 && (mask_faisca_area > 0.01 || (usar_textura_formato && mask_tex > 0.01))) {
        vec2 uv_f = uv_segura - (direcao_vento * TIME * velocidade_puxao_faiscas);
        
        float tam = faisca_tamanho_base;
        if (faisca_tamanho_radomico) {
            float rt = texture(noise_tex2, uv_f * 3.0).r;
            tam *= mix(faisca_tamanho_min, faisca_tamanho_max, rt);
        }
        
        float sn = texture(noise_tex, uv_f * tam).r;
        float blink = 1.0;
        if (faisca_tempo_radomico) {
            float r_temp = mix(faisca_tempo_min, faisca_tempo_max, texture(noise_tex2, uv_f * 2.0).r);
            blink = sin(TIME * r_temp);
        }

        float limiar = 1.0 - (qtd_faiscas * 0.1);
        if (sn > limiar && blink > 0.0) {
            if (faiscas_com_borda && sn < limiar + 0.02) col = cor_contorno;
            else col = c_mid;
            alpha = 1.0;
        }
    }

    col.rgb *= intensidade_glow;
    float a_final = alpha;
    if (radomizar_alpha) a_final *= mix(alpha_min, alpha_max, (sin(TIME * vel_radomizacao) * 0.5 + 0.5));
    
    COLOR = vec4(col.rgb, a_final * alpha_geral * bounds_mask);
}
Live Preview
Tags
fire
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 Dep Emily

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments