Outline and Glow Shader Sprite 3D
A flexible shader for outlines, glows, and trails for Sprite 3D. It is not the most performant, but it will get you what you need. There are not many answers for this out there so I wanted to post this.
You can adjust fade, thickness, density for performance, etc. If you reduce the Glow Radial Coverage to 1, you can get a faded trail effect. Comments in the code explain things in more detail.
For syncing up the Sprite 3D texture with the shader, see Anonzs’ post here https://www.reddit.com/r/godot/comments/11dklv0/sprite3d_shader/
For another good glow answer that also solves for busting outside the vertex bounds, check out Sithoid’s post here https://www.reddit.com/r/godot/comments/18hko1l/outline_shader_for_sprites3d_rough_but_feel_free/
Shader code
shader_type spatial;
render_mode unshaded,blend_mix,depth_prepass_alpha,cull_disabled,specular_disabled;
uniform sampler2D sprite_texture : source_color, filter_linear;
uniform vec4 line_color : source_color = vec4(1.0,1.0,1.0,1.0); // Glow or outline color
uniform float glowSize: hint_range(0.0, 300) = 15.0; // Size of glow
uniform int glowDensity: hint_range(0, 30) = 3; // How many stamps to repeat in one direction
uniform int glowRadialCoverage: hint_range(0, 32) = 4; // How many directions to spread out
uniform float glowAngle: hint_range(0.0, 6.28) = 1.57; // The starting angle. More important if you want to use this as a trail.
uniform float glowSharpness: hint_range(0.0, 5.0) = 1.0; // Effect how quickly stamps become transparent as they move out
uniform float alphaThreshold: hint_range(0.0, 1.0) = 0.2; // Alpha level a pixel should be considered a glow
//Goes through every single pixle and does thing
void fragment() {
vec4 col = texture(sprite_texture, UV); // Gets color at uv position of pixel
// Sets source image as default pixel
ALBEDO = col.rgb;
ALPHA = col.a;
vec2 pixel_size = 1.0 / vec2(textureSize(sprite_texture, 0)); // Set pixel size
float alph = 0.0; // Start with a 0 alpha to add to with each check
for (int i = 0; i < glowRadialCoverage; i++) { // Goes around in a circle
for (int j = 0; j < glowDensity; j++) { // Extends out
float radians360 = 6.28;
// The angle from which to grab pixel information
float angle = (radians360 / float(glowRadialCoverage))*float(i+1) + glowAngle;
// The distance to reach to grab pixel information
float dist = glowSize * float(j + 1) / float(glowDensity);
// Pixel coordinate to grab
vec2 pixel_coor = vec2( sin(angle) , cos(angle) );
// Gets the pixel based on the previous information
vec4 tex = texture(sprite_texture, UV + pixel_coor * pixel_size * dist);
// Sharpness. If you don't care about this, enable the next line and delete the next 3
//alph += tex.a * line_color.a;
float distFrom = float(glowDensity-j) / float(glowDensity); // Distance iteration number (how far out)
float sharpness = mix(0.0, 1.0, pow(distFrom, glowSharpness) ); // Figure out sharpness level, interplote with distance and Glow Sharpness modifier
alph += (tex.a * line_color.a) * sharpness; // Apply sharpness
}
}
// Adds outline if this part of the image is transparent
if (ALPHA < alphaThreshold){
ALBEDO = line_color.rgb;
ALPHA = alph;
}
// Enabling this line will cut out the image and leave the outline
//ALPHA -= col.a * 10.0;
// if you set blend to add, and set this as a second pass, you'll get a better glow effect
}
Doesnt work lol
Hey! it works perfectly fine.