Search Unity

Rendering of first person weapon model

Discussion in 'FPS.Sample Game' started by AndreasO, Oct 24, 2018.

  1. AndreasO

    AndreasO

    Joined:
    Sep 25, 2012
    Posts:
    90
    Hey,

    can anybody explain how the rendering of the weapon model works?

    I expected to find a second camera that overlays the rest of the scene to avoid weapons to stick through other geometry (walls, characters, etc.) when player moves too near to any of those.

    What I did find is some flag called "_FpsModeFov" inside Lit.shader, for example.
    However, I cannot find any usage of it. So what's going on here? o_O
     
    Last edited: Oct 24, 2018
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Because it not use second camera :) It's all - great opportunities which give us SRP :)
     
    hippocoder likes this.
  3. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Tiny Gun?
    TinyGun.png
     
  4. AndreasO

    AndreasO

    Joined:
    Sep 25, 2012
    Posts:
    90
    Yes, I know that it's not using a second camera. But how is it done with SRP then?
    My search ended at the mentioned variable / flag. I don't know where to look further to understand it.
     
  5. petera_unity

    petera_unity

    Unity Technologies

    Joined:
    May 23, 2016
    Posts:
    41
    The material used on the first person models (hands and weapons) have this flag set. It 'reprojects' the model to a fixed FOV regardless of the FOV the player have selected for the game (either using the config.fov variable or simply by choosing an aspect for the window). If we didn't have this, the weapon would look very stretched on wide fovs.

    Note that we have 'internalized' the HDRP package in our own Packages folder. We work with the HDRP team to over time find best ways to integrate our needs in HDRP. So some day we may switch to clean HDRP package again.

    Our solution to not having weapons sticking through geometry is to make them very small. Try locating the hands in scene view next to something comparable in size. Looks pretty silly there but you cannot tell when in first person view.

    Peter
     
  6. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Do you mind to point out where is this function running at? since HDRP code are quite big, i just cannot find the correct files
     
  7. AndreasO

    AndreasO

    Joined:
    Sep 25, 2012
    Posts:
    90
    Thanks! This helps me a lot. :)
     
  8. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Hi Peter - is it possible to not shrink the weapon? because for example sometimes we need to have an accurate interaction (sword hitting shield) in first person and we want the shield to render on top of the enemy sword and of course not clip with geometry. Too difficult?

    Small doesn't really work in cases like that sadly, since these things can penetrate up to the camera near clip in theory and won't be kept at bay at capsule bounds...
     
    INeatFreak likes this.
  9. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
  10. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    Curious why you guys don't just put it at the end of the render queue, that's what I've always done to avoid this issue. That way you can keep everything scaled correctly, not use double cameras (wasteful), and it always draws over everything.
     
    Last edited: Oct 24, 2018
  11. unity_mad_coder

    unity_mad_coder

    Joined:
    Oct 22, 2016
    Posts:
    7
    Like he said, the shader is used to 'reproject' the mesh using a custom projection matrix with a different field of view from the camera and not to avoid sticking through geometry.
     
    Last edited: Aug 2, 2019
  12. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    Yah I got that, I just didn't think the two were mutually exclusive. Custom FOV, then have it render AFTER everything else.
     
  13. Mogens_H

    Mogens_H

    Unity Technologies

    Joined:
    Mar 7, 2017
    Posts:
    20
    Having a custom FOV for 1P character is proably not a good idea if you have a game where 1P char does a lot of interaction with the world. It is a tradeoff we make to make sure 1P stuff isnt stretched depending on what FOV the user sets.
    You can actually see in some 1P games that has world interactions (like grabbing edge of wall when climbing) that the normal 1P arms (with fixed FOV) leave screen and a pair of world fov arms quicky appear to do the interaction.
     
    joaoborks likes this.
  14. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    That's normally what people do isn't? even though it still using custom projection matrix, the Shooter Hand and the world interaction hand have different FOV.
     
  15. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I cannot unsee it now I've seen it - thanks a lot :)

    Do you have a recommendation for the clipping issue for melee combat FPS games? not worried about the FOV because we don't have fov adjustment for melee FPS and shrinking them just breaks the whole thing when they interact. It would be better to just say "OK you're on top!"
     
  16. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Hackish way? separate the collider and the renderer. Just make sure the animation are synched :p
     
  17. Mogens_H

    Mogens_H

    Unity Technologies

    Joined:
    Mar 7, 2017
    Posts:
    20
    Not hackish IMO. I am not a big fan of "physics based" solutions where animations move the colliders that does the hit detection. I would go for a solution where collision detection is detached from animation and animations are made to "fit". This makes it a lot easier to tweak gameplay and allows you to resolve collisions early and choose fitting animations.
    But when swinging long things around I think it is impossible to avoid clipping completely (and not a huge problem imo - if it happens fast).

    We actually have melee weapons on our (very long) list of game features we would like to make. But it will probably be on a 3P character (another thing we would like to do). But no promises ;)
     
    PutridEx, Reanimate_L and hippocoder like this.
  18. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Well the hack doesn't actually work. The physics aren't the problem. the sword from the enemy penetrates (clips) through the shield and so on. We simply want to make sure the shield renders on top of most things but not all (UI and particles for example).

    Yep that's with a tiny 0.2 scale shield right in my eye.
     
    INeatFreak likes this.
  19. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Ah good point, especially the shield clipping and the fast moving animation part.
     
  20. Mogens_H

    Mogens_H

    Unity Technologies

    Joined:
    Mar 7, 2017
    Posts:
    20
    I see. Perhaps some shader stuff can be done for shield and/or the enemy weapons. Alternatively some ik or other modification of enemy animation depending on shield position.
     
    hippocoder likes this.
  21. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I'll give it a go! but I'm sorry for dragging the thread a bit tangent :)
     
  22. Vestergaard

    Vestergaard

    Unity Technologies

    Joined:
    Oct 20, 2016
    Posts:
    31
    Our options were

    1. Rendering in multiple passes - hard to do on stock hdrp without heavy modding, performance heavy, have to solve for all kinds of effects that depend on blur or a correct depth buffer.

    2. Our tiny gun with FoV Solution, as far as I can tell similar to what they do in doom (where it also does clip sometimes). Whenever you interact with the world in doom they pull down your tiny hands and bring up the real but quite distorted full scale hands to interact with the world. This solution works well at all different aspect ratios and fov's as your hands and gun looks great even on ultrawide and multi-monitor setups.

    3. Rendering completely naive and just accepting intersections, intersection can be limited by either nudging the player when you swing around a weapon near a wall and having an animation that raises the weapon to avoid intersection. But it doesnt solve for it looking silly on wide monitors, or even being quite distorted in regular field of view.

    We found:

    1. unfeasible to maintain for us in isolation (the HDRP team is not at our beck and call)
    2. Only requires a minor hack to the needed shaders and was a good compromise working with most rendering features out of the box, also ultrawide monitors seem increasingly common.
    3. Nudging the player in a fast-paced fps seemed wrong, and it looks bad even in a regular fov.
     
    Last edited: Oct 27, 2018
  23. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    How about doing number 2 but with custom projection matrix and not tiny gun? since it can be done in Legacy pipeline
     
  24. Vestergaard

    Vestergaard

    Unity Technologies

    Joined:
    Oct 20, 2016
    Posts:
    31
    So we do modify the projection matrix we just don't squash it in the depth as that would create strange artefacts with postfilters that are depth dependant like our SSAO or contact shadows, and cause issues for people wanting to do any kind of depth based effect on top of the game.

    At the end of the day the solutions we know of have pro's and con's and which to pick has been heavily contested internally as well :)
     
  25. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926


    if you take a look in this video from 3:17 to 3:50, it really seems like the first person gun+hands mesh is full-sized. Really not sure how they handle this. In some cases the gun is really really huge and would definitely clip through walls all the time if it was rendered without any special tricks

    EDIT: actually.... I noticed at 0:13 that the arms+gun mesh is rendered on top of the BFG shot. Seems like they might just be rendering it on top of everything else
     
    Last edited: Jan 24, 2019
    hippocoder likes this.
  26. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    My instinct would be a simple stencil pass or something.... Seb mentioned somewhere you could probably just easily reserve a range of depth. I don't know how I'd do either to be honest, in HDRP :)

    In my case I'm just going to have to let the clipping happen, or perhaps render something to texture then composite it.
     
  27. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    In URP, Stencil pass seems the way to go. It is efficient, theres a tutorial to set it up in ~15min and it just works.
    Now after switching from URP to HDRP, the HDRP-Asset / scriptable render pipeline asset seems to be missing so theres no place to set this up?

    I don't really want tiny guns because
    • it is harder to work with them (zooming, unzooming the camera whenever you work with them)
    • incorrect shadows
    • way harder to set up projectiles, think a rocket launcher (or bazooka) where you see the rocket at all times
    • harder setup of physical interactions like knife kills and other melee weapons
    • having to adjust the near clip plane of the camera, limiting the far clip plane or increasing possible Z-fighting issues
    • and probably a lot of other issues of which I will find out later in development .. scary

    Using camera stacking with two cameras is bad for performance and you can't use fog in your post processing / sky and fog volume - or the fog of the weapon camera will be rendered on top of the game camera.

    So whats the way to go now? Is there any option similar to the URP version with the stencil pass? How to solve this very common problem in HDRP right now?

    PS: I tried a bunch of things already, looked at different forum posts and none seems to have a good solution (like the one in URP), thats why I am asking now.
    Theres a youtube channel, using a Custom Pass Volume (with DrawRenderersCustomPass), but setting this up for every single material on my weapon and arm models is just insane ..
     
    the_real_ijed and hippocoder like this.
  28. OneManArmy3D

    OneManArmy3D

    Joined:
    Jun 2, 2011
    Posts:
    191
    rly? did they fixed problem with shadows (when turn on cascades)?
     
    Last edited: Jun 18, 2020
  29. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    I guess so - I saw some issues with shadows, I could see them throught my opaque weapon but this went away (or I stopped noticing it? idk, but I think it got fixed), now I am working with HDRP, so I can't check it anymore.

    Edit: Now I am using camera stacking on HDRP, which decreases performance and you have to turn off the fog on your weapon camera (advanced settings .. ) but everything works now as expected, except for Gizmos/Handles - they are drawn with the wrong camera in gameView.

    Edit2: Camera Stacking was a performance killer, so I switched to using the shader instead, scaling the weapon and well, actually, weapon clipping is one of the least important things as indie dev. Considering proper AI, fluid movement, non-jittery elevators, good pacing, consitent and logical world building, good performance, nice graphics, understandable and easy-to-use UI - weapon clipping is really just a small detail and I decided to stop caring about it, so I can focus on making a good game instead.
     
    Last edited: Oct 19, 2020
    andreyefimov2010 likes this.
  30. fct509

    fct509

    Joined:
    Aug 15, 2018
    Posts:
    108
    Where does one adjust the render fov for the weapon?
     
  31. karstenv

    karstenv

    Joined:
    Jan 12, 2014
    Posts:
    81
    There is a parameter on its shader for that....
     
  32. fct509

    fct509

    Joined:
    Aug 15, 2018
    Posts:
    108
    What I meant was, where do I change the value for the parameter, so that the the value that I want, is the one that gets used for that object, when the game creates a new instance of said object? I can play around with the parameter's default value inside the shader all I want, once the material has been created, changing the default value won't alter the value in the material. On top of that, if there's a prefab or scriptable object holder a value that gets applied to the material (in code), then the value that's set on the material won't matter either.
     
  33. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    Yes? Thats why it is called a default value. If you want the same FOV for all objects using the shader, just don't expose the value --> make it a Vector1 Node, instead of a property but then you can't change it at runtime.
    If you want to change it at runtime and you want to change it for all GameObjects using the same material you have to use MeshRenderer.sharedMaterial API - and then set the value via sharedMaterial.SetFloat() API .

    This will set it for one material, if you have more than one material and want to set the FOV for all of them, you have to create a List of all these materials and then iterate throught them, to set the FOV for every single material.
    Pseudocode:
    foreach(Material mat in myFovMats) mat.SetFloat("_FpsModeFov", 40);


    You just have to be aware that if you change a material Asset and exit play-mode, all changes will stay because you changed an Asset.
     
  34. ristetutureski

    ristetutureski

    Joined:
    Jan 29, 2019
    Posts:
    22
    We just wrote our blog for solving a similar problem described in this post. This is our blog: https://www.intetic.com/blogs/unity-hdrp-render-object-on-top-of-everything/

    Basically, we are using two Custom Passes that we are overriding Material on a specific layer, so it's not tied to a Material, but to the object that belongs to a specific layer.

    Hope we helped devs that have a similar situation.
     
    PutridEx and gesicht like this.
  35. fct509

    fct509

    Joined:
    Aug 15, 2018
    Posts:
    108
    Wow, I haven't looked at this for a while but I see my meaning never got through. Somewhere, there's an prefab or a scriptable object, with a setting that holds a value that I can change without having to make any alterations to the shader. By changing the value in that location, I can change the FOV that get's used in the weapon within the game. Yet, there are multiple levels of that value with different priorities, so where is the one that is intended to be set when someone wants to set the FOV? Why write code that overwrites a feature that does the very thing I want to do, when I can just use said feature. I'm not asking how to brute force an override. I'm asking if anyone knows the location in which they put the setting that does end up getting used for the weapon's FOV.

    Well, at least that's what I was looking for back when I was going through the FPS Sample. At this point, that information is no longer useful to me.
     
  36. karstenv

    karstenv

    Joined:
    Jan 12, 2014
    Posts:
    81
    The feature is on the weapons shader. Find a weapon in the game and look at its material. On the shader there is something called FOV overrride(or something like that).