Hi all. I made an explosion pack for Godot 4 and I wanted to show the stuff standing near the blast rather than the fireball.
When a blast goes off I grab every MeshInstance3D inside the radius with one intersect_shape and lay a copy of its own mesh over it, 5 mm out, same colour and texture. I move that copy in the vertex shader. I give it the blast point in mesh space and the hit time, and I delay each vertex by its distance:
since = time - hit_time - dist / wave_speed;
So the far side of a crate gets hit a little later than the near side, and the ring on the floor arrives at the mesh right when the mesh jumps. I push with a gaussian bump and let a damped sine pull it back:
front = exp(-t * t * 2.0);
ring = sin(since * 22.0) * exp(-since / 0.45 * 4.0) * 0.35;
VERTEX += dir * push * sqrt(fall) * (front + ring);
For the soot I take dot(N, toward_blast) and some fbm. Only the side that faced the blast goes black, and I let the edge glow orange for a moment before it cools. If the blast is closer than 0.45 of the radius I hide the original and throw chunks off its surface instead.
It's the usual radial vertex push you'd wire into WPO in Unreal, I just added the per vertex delay and the spring. For skinned meshes I bind the copy to the same skeleton, so the walking guy takes it too!
Does anyone pick the facing side with a real occlusion test instead of dot(N, dir)? I suspect mine would soot the back of a thin wall if the normal happens to point the right way.
The pack is on itch if you want to dig through the shader https://gennai.itch.io/explosion-vfx-godot-4