Sprite3d outline shader with twinkle for Godot4(Support Billboard)

Usage:

1. Create a 3d scene

2. Add Sprite3d with picture texture

3. Attach shadre to material overlay, attach same picture texture to `Sprite Texture`

 

Keyword:outline, sprite3d, sparkle,glitter,twinkle,radiate, godot4, spatial,  billboard

Shader code
// ref : https://godotshaders.com/shader/sprite3d-outline-working-billboard/
// 描边+闪烁
shader_type spatial;
render_mode unshaded, blend_mix, depth_prepass_alpha, cull_disabled, specular_disabled;

uniform sampler2D sprite_texture : source_color, filter_nearest;
uniform bool enable_billboard = true;
uniform bool enable_outline = true;

// 简单像素描边参数
uniform vec4 simple_outline_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform float simple_outline_width : hint_range(0, 10) = 1.0;

// 闪烁控制参数
uniform float flash_speed : hint_range(0.1, 10.0) = 5.0;
uniform float flash_min_alpha : hint_range(0.0, 1.0) = 0.2;
uniform float flash_max_alpha : hint_range(0.0, 1.0) = 0.8;

void vertex() {
    if (enable_billboard) {
        vec3 world_origin = (MODEL_MATRIX * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
        float scale_x = length(MODEL_MATRIX[0].xyz);
        float scale_y = length(MODEL_MATRIX[1].xyz);
        vec3 cam_right = normalize(INV_VIEW_MATRIX[0].xyz);
        vec3 cam_up    = normalize(INV_VIEW_MATRIX[1].xyz);
        vec2 local = VERTEX.xy;
        vec3 world_billboard = world_origin
            + cam_right * local.x * scale_x
            + cam_up    * local.y * scale_y;
        POSITION = PROJECTION_MATRIX * VIEW_MATRIX * vec4(world_billboard, 1.0);
    } else {
        POSITION = PROJECTION_MATRIX * VIEW_MATRIX * (MODEL_MATRIX * vec4(VERTEX, 1.0));
    }
}

void fragment() {
    vec4 col = texture(sprite_texture, UV);

    // 初始设置为完全透明
    ALPHA = 0.0;

    if (enable_outline) {
        // 简单像素描边+闪烁模式
        vec2 pixel_size = simple_outline_width / vec2(textureSize(sprite_texture, 0));

        // 8方向采样(更平滑的描边)
        float max_alpha = 0.0;
        for (int x = -1; x <= 1; x++) {
            for (int y = -1; y <= 1; y++) {
                if (x == 0 && y == 0) continue; // 跳过中心点
                vec2 offset = vec2(float(x), float(y)) * pixel_size;
                float sample_alpha = texture(sprite_texture, UV + offset).a;
                max_alpha = max(max_alpha, sample_alpha);
            }
        }

        // 计算闪烁因子(0~1 平滑变化)
        float flash_factor = (sin(TIME * flash_speed * 3.14159) + 1.0) * 0.5;
        float flash_alpha = mix(flash_min_alpha, flash_max_alpha, flash_factor);

        // 只显示描边区域,不显示中心内容
        if (col.a < 0.99 && max_alpha > 0.01) {
            // 描边区域(应用闪烁)
            ALBEDO = simple_outline_color.rgb;
            ALPHA = simple_outline_color.a * flash_alpha; // 仅描边闪烁
        } else {
            // 中心区域保持完全透明
            ALPHA = 0.0;
        }

    } else {
        // 不启用描边时显示原纹理
        ALBEDO = col.rgb;
        ALPHA = col.a;
    }
}
Live Preview
Tags
billboard, glitter, godot4, outline, radiate, sparkle, Spatial, sprite3D, twinkle
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.

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments