FPS Shader - No WallClipping and Working Shadows

LINKS AT BOTTOM
https://www.youtube.com/watch?v=GknjdVIsU8c

Hello everyone,

Recently I’ve been contacted for help on my initial findings on making a proper first person shader to prevent the weapon model from clipping into the environment. As I love FPSs I figured I’d delve back into and make it work proper as well as share a working version of it people could use as a basis to make their own (after all we’re all using different workflows, shader graph editors and all that kind of stuff).

So the initial idea remains the same. Having a pass at “Geometry+1” that forces writing to the depth buffer and another at “Geometry+2” (these are RenderQueues, which determines shader execution order) that renders the object that is properly rendered on top of everything thanks to the first pass. I have however made a few improvements. Now the example shader is as close as I could make it to a standard surface shader with metalness and normal maps supported.

You can also now customize the FOV of the weapon model without affecting the camera. This is done using the Viewmodel Matrix Manager script to the player or camera and adjusting that with a slider. This is however not optimal. I update the shader variables every frame for testing purposes. In your final product this should be done at level load OR when the player actually changes the slider in your settings (if you have a custom viewmodel FOV slider that is, most games don’t).

I’ve also created a basic example script that sets up your model automatically for you. This basically allows you to have a material for the editor (to avoid the weird virtual glitches that custom FOV incurs in the editor view) while still having the correct material during play.

This is only supported in forward rendering for the built-in pipeline so keep that in mind

For URP and HDRP : the same basic principles can very likely be applied there. The advantage is you probably don’t even need a script to get the camera’s inverse projection, as that seems to be available in shader graph.

For shadows : If you need the player model to cast shadows you’re in for a treat. You’ll need to have an invisible shadow casting model (not very hard). Then you have 2 possible solutions :

  • In the invisible shadowcasting model, increase the shadowmap bias. This will make it so this model doesn’t shade your viewmodel (which would result in potentially bad shadows, like the third person’s gun shading the first person one).

  • Cast the invisible shadowcasting model shadow to a secondary shadow map, and sample this map on top of Unity’s default one in all of your shaders EXCEPT the first person model. A good research starting point if you want to do that is this article : Custom Shadow Mapping in Unity. I am going to walk through how to… | by Shahriar Shahrabi | Medium This will be a lot of work and is a little bit heavier on performances, but it should be the best solution afaik.

For most cases though you won’t need shadows. Even modern AAA games such as Doom 2016, Doom Eternal or Apex Legends don’t cast a shadow of your player model. FEAR and CoD Warzone seem to be a couple of the very few example of games that go to these extremes. More often than not, especially in a fast paced game, a self shadow will be more distracting than anything else !

tl;dr : A working FPS shader that prevents clipping with a few nice features. Easy to port or modify with beginner shader knowledge. Incompatible with deferred, URP and HDRP (though could potentially be ported to URP and HDRP using same principles).

Complete Unity Project - Example Scene Included - tested in 2020.3.32f1 : https://drive.google.com/file/d/1HeeOL6rKSjag2fLNo7FN79AFCJgHUUPX/view?usp=sharing Credits : AKM by Delthor Games Stylized Low-Poly Gun by POLYART 3D GAME FPS Controller’s code by Sharp Coder

Unity Package with the bare minimum to include in your own project : FPViewModel.unitypackage - Google Drive

I recommend opening the project first to see how things are setup.

Hope you all enjoy, have a good day everyone and have fun with that !

Small edit : the major advantage over dual camera is that the model receives proper shadow attenuation and lighting color and as such receives cast shadows and prevent light bleeding through walls (well for the most part, might still show through thin walls).

3 Likes

Thank for share this, It should be exactly what I looking for.

Cool! Maybe put it on the asset store :stuck_out_tongue:

Can you make HDRP version please?

1 Like