Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

What Camera.main.WorldToViewportPoint does? How to save transform and call it later?

Discussion in 'Scripting' started by BinaryBanana, Mar 4, 2019.

  1. BinaryBanana

    BinaryBanana

    Joined:
    Mar 17, 2014
    Posts:
    81
    Hi,
    I need to call Camera.main.WorldToViewportPoint for a list of Vector3 points but I need to do it over few frames. In few frames, camera will move and it won't be accurate for the points. So the question is, how can I save camera matrices and calculate viewport on my own, so exactly what Camera.main.WorldToViewportPoint does?

    Thanks!
     
  2. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,778
    Why don't you want to just call Camera.main.WorldToViewportPoint() on your list of points every frame?
     
  3. BinaryBanana

    BinaryBanana

    Joined:
    Mar 17, 2014
    Posts:
    81
    Performance. I only have time to do initial calculations which will create more points. Each frame I am doing some part of the work.
     
  4. BinaryBanana

    BinaryBanana

    Joined:
    Mar 17, 2014
    Posts:
    81
    I think I found the solution :)

    Code (CSharp):
    1.        
    2. // Point "point" is already in world coordinates, not need for Transform.localToWorldMatrix
    3.  
    4. // screenPoint returns in 0-1 range
    5. Vector2 screenPoint = Camera.main.WorldToViewportPoint(point);
    6.  
    7. // Same as above
    8. Matrix4x4 V = Camera.main.worldToCameraMatrix;
    9. Matrix4x4 P = Camera.main.projectionMatrix;
    10. Matrix4x4 MVP = P * V; // Skipping M, point in world coordinates
    11. Vector3 screenPos = MVP.MultiplyPoint(point);
    12. Vector3 screenPointSame = new Vector3(screenPos.x + 1f, screenPos.y + 1f, screenPos.z + 1f) / 2f;
    13.  
    14. // screenPoint is the same value as screenPointSame :)
    15.  
    This was helpefull: https://answers.unity.com/questions/12713/how-do-i-reproduce-the-mvp-matrix.html
     
  5. BinaryBanana

    BinaryBanana

    Joined:
    Mar 17, 2014
    Posts:
    81
    Other scenarios might be around execution on background threads (not my case though).
     
  6. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,778
    Yeah, i was just about to say all the matrices are accessible on the camera.

    Unity api reference is king.

    Edit:
    I don't know if the compiler does this or not, but multiplying by 0.5 will be faster than dividing by 2. Depending on how many points you have it might make a difference.

    Also, construct your MVP outside the loop of points once per frame, but i'm sure you're on top of that.​
     
    BinaryBanana likes this.
  7. Art-Leaping

    Art-Leaping

    Joined:
    Apr 2, 2015
    Posts:
    22
    Just adding some terminology clarity for anybody finding this in the future - technically this is not the MVP matrix, it's just the VP matrix.

    The M comes from "Model" which would be a third matrix that goes from Object to World space of the object you're rendering. You don't always need or want that though - such as if you're just drawing a mesh into screenspace at default orientation relative to the screen/camera (as one might do to render a light flare).