Billboard Sprite3D Hitflash (Godot 4.x)

Use with Sprite3D and AnimatedSprite3D nodes. It works best if set as the material override (under GeometryInstance3D tab).

Tips:

After setting up the shader copy the texture from the Sprite3D and set it as ‘Tex’ in the shader parameters. If you would like to use this shader with an AnimatedSprite3D set tex as the texture containing all the sprites in your sprite frames (the sprite sheet). I’m not sure if it’ll work if you aren’t using a sprite sheet.

You can set the flash colour and toggle the billboard setting in shader parameters also. Animate the hitflash with the active parameter using an animation player or do it in code with something like:

$Sprite3D.material_override.set_shader_parameter("active",true)

Note: If you don’t need any billboarding comment out the entire vertex() function in the gdshader.

Shader code
shader_type spatial;
render_mode unshaded, cull_disabled, depth_draw_opaque, depth_prepass_alpha;
// Remove unshaded if you want shading
// Replace cull_disabled if you want to only show one side (cull_front, cull_back)
// Reference for depth ::: https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/spatial_shader.html#render-modes

uniform bool active = false; // Sets pixels to flash color when true
uniform vec4 flash_color: source_color = vec4(1.0,1.0,1.0,1.0); // The color to use when active
uniform bool y_billboard = false; // Enables Y-Billboarding when true
uniform sampler2D tex: source_color; // A copy of the texture for the Sprite3D or AnimatedSprite3D 

void vertex() {
	// You can comment out this function if you don't need billboarding
	if (y_billboard == true) {
		MODELVIEW_MATRIX = VIEW_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), INV_VIEW_MATRIX[2].xyz)), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))), 0.0), MODEL_MATRIX[3]);
	}
	else {
		MODELVIEW_MATRIX = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);
	}
	MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);
}

void fragment() {
	vec4 col = texture(tex,UV);
	vec4 set_col = col;
	if(active == true) {
		set_col = flash_color;
	}
	ALBEDO = vec3(set_col.r,set_col.g,set_col.b);
	ALPHA = col.a;
}
Tags
billboard, flash, hit, hitflash, sprite3D
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 Alkaliii

Procedural Cyclic Slash

Related shaders

Billboard Sprite3D Sway (Godot 4.0)

Sprite3D Indexed Color Palette Swapping Shader

Muzzle flash Z-axis billboard

Subscribe
Notify of
guest

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
xiaqii
1 year ago

this question cost me one day.
very very thanks for you.

razage
razage
10 months ago

If you want to use this with pixel art or if your sprite seems “fuzzy”, you should change the uniform sampler2D as such:

uniform sampler2D tex: filter_nearest, source_color;

You can add repeat_disabled to that list too, if needed.

Elsen
5 months ago
Reply to  razage

You’re the light at the end of a 1h tunnel of googl’ing; thank you!

Richard Ellicott
Richard Ellicott
5 months ago

the way vertex is used there just surprised me, that is genius… i’m actually trying to make a laser shader, something about how the Sprite3D is like if you want, a laser facing the upwards y direction

meditating on your code is gonna give me the answer cheers

wabbit
wabbit
1 month ago

What trickery did you do to get this to work on an animated sprite?

Camelot Moon
Camelot Moon
1 month ago

To anyone searching around in the future for a solution like we were, the combination of these two shaders was finally the fix for our Sprite3D clipping issues. Just do billboarding, then the depth adjustment in the vertex shader, and tune the depth amount parameter until it looks right.

You might also have to play with the Y/Z position of your sprite so that it still looks like it touches the ground, and will also probably want a script that sets the shader texture to the one set on your sprite.

Billboarding:
https://godotshaders.com/shader/billboard-sprite3d-hitflash-godot-4-x/

Depth Adjustment:
https://godotshaders.com/shader/depth-adjustment-for-clipping-protection/