How would you implement bullet trails?

Hi folks,

I’m looking for some input and ideas regarding how one would go about implementing a bullet trail effect - that is, you shoot a gun and you get some visual indicator to illustrate where the bullet has travelled.

I’ve never done this sort of thing before, so I’m just not sure which route to take - or what the available routes even are! So I invite you to share what has worked for you before, or what you’ve seen, when it comes to trail effects.

Things I have either tried or read about so far:

  • An actual mesh object for the bullet - looks rubbish, if it can even be seen moving at such fast speeds
  • A plane with a texture moving along the trajectory of the bullet - my implementation looked bad, perhaps it needs cylindrical billboarding done via shader (not my forte)
  • A plane stretched from start to end of trajectory with either a texture or flat colour & shader to fade it in/out
  • Create a particle system for three, use sprites
  • Some shader magic I’m sure

I haven’t done any such thing either.

But I would go for a particle system, with the bullet itself being the emitter, dragging a trail of particles behind itself like a comet. You could control the visibility of such high-speed objects via modification of the average (random) lifespan of those particles, and maybe some random variations of their color/transparency over time.

You might even get some inspiration from a Google image search for “bullet trail underwater”.

2 Likes

Here are three demos for inspiration.

https://codepen.io/boytchev/pen/qBLNEVZ
https://codepen.io/boytchev/pen/QWzjOMx
https://codepen.io/boytchev/pen/mdgyQGz

For bullet effects the trajectory should be a straight line (unless you want to model ballistics) and motion should be much faster. You can also consider the limitations of human brain – if a motion is too fast, the brain will not see the fine details, so you may spare efforts on the artistic design of the bullet.

7 Likes
attribute vec3 offset; // world position
attribute vec2 scale;
attribute vec3 direction;
void main(){
vec3 vRotated=vec3(position.x*scale.x,position.y*scale.y,position.z);
vec3 vLook=normalize(offset-cameraPosition);
vec3 xaxis=normalize(cross(vLook,direction.xyz));
vec3 zaxis=normalize(cross(xaxis,direction.xyz));
mat3 rotMatrix=mat3(vec3(xaxis.x,direction.x,zaxis.x),vec3(xaxis.y,direction.y,zaxis.y),vec3(xaxis.z,direction.z,zaxis.z));
vec3 vPosition=vec3(dot(rotMatrix[0],vRotated),dot(rotMatrix[1],vRotated),dot(rotMatrix[2],vRotated));
gl_Position=projectionMatrix*modelViewMatrix*vec4(vPosition+offset,1.0);
}


Thanks everyone for your suggestions and examples - loads for me to consider now!

I think I have to try everything, to see what works best for me :smiley: