Particle based trail
A continuous trail effect for creating sword slashes, light sabers, etc. It works by packing trail data into the TRANSFORM
, making it accessible by the draw pass shader.
This effect should work in Godot 3, and Godot 4 with minor changes.
A SMALL UPDATE:
There is a slightly better way to set this up than described below. I will work on tweaking the code, so stay tuned for an update soon… In the meantime, I recommend using my up-to-date GPUTrail addon.
SET UP:
- Add a new GPU Particles node into the scene
- Set
Fixed FPS
greater than 0, and setSpeed Scale
to the same value asFixed FPS
. This number determines the length of each step in the trail - Set
Amount
to a power of 2 (e.g. 8, 16, 32, 64), and setLifetime
to the same value asAmount
. This number determines the number of steps in the trail - Set
Local Coords
tofalse
- Assign the particle shader to the
Process Material
slot - Add a new
QuadMesh
to the draw pass, and assign the following spatial shader. This is required to render the trailshader_type spatial; render_mode unshaded,blend_add,world_vertex_coords,cull_disabled; uniform sampler2D tex; void vertex(){ vec3 a = mix(WORLD_MATRIX[3].xyz,WORLD_MATRIX[2].xyz,UV.y); vec3 b = mix(WORLD_MATRIX[0].xyz,WORLD_MATRIX[1].xyz,UV.y); VERTEX = mix(a,b,UV.x); UV.x = (INSTANCE_CUSTOM.w-1.0 - UV.x)/INSTANCE_CUSTOM.z; } void fragment(){ vec4 T = texture(tex,UV); ALBEDO = T.xyz; ALPHA = T.w; }
USAGE NOTES:
You need to restart emission after changing settings
Pass a texture or color ramp to the draw pass shader
The emission line is defined between -1 to 1 of the local Y axis, scale the GPU Particals node as required
Shader code
shader_type particles;
render_mode keep_data,disable_force,disable_velocity;
void vertex() {
vec3 a = (EMISSION_TRANSFORM*vec4(0,-1,0,1)).xyz;
vec3 b = (EMISSION_TRANSFORM*vec4(0,1,0,1)).xyz;
if(CUSTOM.w == LIFETIME){
CUSTOM.z = LIFETIME;
CUSTOM.w = 0.0;
}
if(CUSTOM.w == 0.0){
TRANSFORM[0].xyz = b;
TRANSFORM[1].xyz = a;
TRANSFORM[2].xyz = a;
TRANSFORM[3].xyz = b;
}
if(CUSTOM.w == 1.0){
TRANSFORM[0].xyz = b;
TRANSFORM[1].xyz = a;
}
CUSTOM.w++;
}