FPS games have explicit Z layering. The common implementation is e.g.
- Render scene
- Clear depth
- Render gun
Some games do more complicated processing to avoid the extra clear. It’s always FPS specific and really really really painful.
Some games change the output depth and then have to go through crazy hoops to support certain styles of shading - e.g. since your depth buffer data is not convertible to the position of the pixel any more without knowing the type, you have to mask the gun with stencil and when you do full-screen postprocessing - for ROBLOX this would apply to SSAO and water reflections - you use one of the two camera parameters to reconstruct the depth.
Unfortunately, GPUs don’t have a good way to do this. We can’t really implement this in a general way because of this - most games that do this have literally 2 values for “ZIndex” and one of them is always the gun and there may be additional content restrictions e.g. for transparent objects.