Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Finding an object's position as if the field of view was different

Discussion in 'Universal Render Pipeline' started by iv2b, Jan 12, 2021.

  1. iv2b

    iv2b

    Joined:
    Aug 2, 2018
    Posts:
    25
    Hey, i've been messing with URP/SRP recently, i'm attempting to make a first person controller.

    What i've been trying to do is drawing the first person view (arms/held items/etc) with a different field of view compared to the camera's fov.
    I achieved this using the camera override in the RenderObjects render feature, like this:
    upload_2021-1-12_15-21-4.png

    And it works like a charm: https://i.imgur.com/HDgCbe0.mp4

    However, what i'm trying to do now is to spawn gameobjects in the real field of view, but based on the fake field of view.

    So for example: I am holding a pistol, i want the bullet to appear right at the muzzle, instead of forward. However the issue is that the muzzle has a different position on the screen due to the different field of view.
    What i've been trying to do, naively, is to grab the muzzle's position in world space and doing
    Camera.WorldToViewportPoint(target.position)
    , which of course doesn't work as the field of view is different.

    So the question is:
    I have a fov of A, i do WorldToViewportPoint and i get a coordinate A (between 0,0 and 1,1)
    How do i find which coordinate i'd obtain if the field of view was B instead?

    I tried changing the camera's field of view just before that line but it didn't seem to change anything.
    Thank you all in advance. :)

    *edit*
    This is what happens if i try to draw a gizmo in the same place of the cube, it appears in a different position due to the different field of view:

    Meanwhile, the cyan cube represents the desired position:
     
    Last edited: Jan 15, 2021
  2. iv2b

    iv2b

    Joined:
    Aug 2, 2018
    Posts:
    25
    Additional information, this should be the code that is tweaking the field of view of the arm/cube:

    Code (CSharp):
    1. Matrix4x4 projectionMatrix = Matrix4x4.Perspective(m_CameraSettings.cameraFieldOfView, cameraAspect,
    2.                             camera.nearClipPlane, camera.farClipPlane);
    3. projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, cameraData.IsCameraProjectionMatrixFlipped());
    4.  
    5. Matrix4x4 viewMatrix = cameraData.GetViewMatrix();
    6. Vector4 cameraTranslation = viewMatrix.GetColumn(3);
    7. viewMatrix.SetColumn(3, cameraTranslation + m_CameraSettings.offset);
    8.  
    9. RenderingUtils.SetViewAndProjectionMatrices(cmd, viewMatrix, projectionMatrix, false);
    Taken from here: https://github.com/Unity-Technologi...universal/Runtime/Passes/RenderObjectsPass.cs

    What i'm trying to do is:
    I have a transform t (P1 in the image).
    1. Use Camera.WorldToScreenPoint (or WorldToViewportPoint, whichever is handier) to find the coordinate (x,y) that tells me where t is on the screen. This would be P1' in the image.
    2. Figure out where (x,y) would be if the field of view was different (eg: 100 instead of 60), finding P2' (this is where i'm stuck)
    3. Extend a line from the camera and through P2' to find P2

    I'm really not sure how i'm supposed to do this or where else i can ask for help.
    If anyone knows the answer to either, please let me know!