Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Xroft666 · Mar 13, 2014 at 11:18 AM · camerascreentoworldpointworld spaceprojectionmatrix

screen space to world using camera.projectionMatrix

Hi, consider this is what I have:

     private void Rotate(Vector3 mouseMoveDelta)
     {
         Vector3 oldPos = Input.mousePosition + mouseMoveDelta;
         Vector3 newPos = Input.mousePosition;
         
         Vector3 oldSwipe = cam.ScreenToWorldPoint(new Vector3(oldPos.x, oldPos.y, 15f));
         Vector3 prevSwipe = cam.ScreenToWorldPoint(new Vector3(newPos.x, newPos.y, 15f));
 
         swipeDir = (oldSwipe - prevSwipe)  * swipeSensetivity ;
    }

This is a usual approach to get world spaced mouse movement delta. So the idea is to do the same thing, but in a proper way - using projection matrix. You can see a lot of problems in the previous snippet: I already have the delta as input, so i don't want to recalculate it but in the world space. I am trying to get rid of Input.mousePosition here. The value is just a delta, meaning that we don't actually need to consider the camera's location and rotation. Meaning that only projection must be applied. Basically, what should be working - is this:

 Vector3 worldSpacedDelta = Camera.main.projectionMatrix.inverse.MultiplyPoint( new Vector3(delta.x, delta.y, 15f) );

But I can't get it right, it's quite hard trying to make sense of random values. Maybe anyone already has the right solution to this?

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Hellium · Feb 01, 2020 at 03:03 PM 0
Share

I am trying to achieve the same thing. I want to compute a world point from viewport (or screen) space according to a matrix. I don't want to use the camera to compute this for me because I would have to set some specific parameters to the camera, compute the points, and revert the parameters afterwards.


The final rendering performed by a camera uses three matrices:

  • World - $$anonymous$$atrix taking the vertices in object space and transforms them to world space. It is the combined transforms of all objects in a hierarchy.

  • View - $$anonymous$$atrix transfor$$anonymous$$g world space point into view/camera space.

  • Projection (and clip) - Defines the 'distortion' (for lack of a better word) to apply to the vertices to simulate viewing something with human eyes (perspective) or orthographically. It also defines the clipping rectangle (the screen).


Source: https://www.reddit.com/r/Unity3D/comments/1pws40/cameraprojectionmatrix_vs/


I've tried to do this but without success:

 $$anonymous$$atrix4x4 matrix = ($$anonymous$$atrix4x4.Ortho(left, right, top, bottom, nearClipPlane, farClipPlane) * cameraTransform.worldToLocal$$anonymous$$atrix).inverse;
 Vector3 point = matrix.$$anonymous$$ultiplyPoint3x4(new Vector3(1, 1, distFromCamera));


 // C++ : compute the matrix
 glm::mat4 $$anonymous$$VPmatrix = projection * view * model; // Remember : inverted !

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#cumulating-transformations--the-modelviewprojection-matrix

avatar image Bunny83 Hellium · Feb 01, 2020 at 04:17 PM 1
Share

I'm not sure if you have seen this question. Also make sure you read the comment below my answer. It should cover this question as well ^^. Note that the viewport position is specified in viewport coordinates (0 to 1) and not NDC coordinates (-1 to 1) for all 3 coordinates.


The important parts are that the worldToCamera$$anonymous$$atrix does a left to right hand conversion since the projection matrix is in OpenGL format and therefore in a right handed system. That means your view direction is the negative z axis unlike Unity's lefthanded space.


Also note that the z value is also the normalized z position unlike Unity's ViewportToWorldPoint method. Finally keep in $$anonymous$$d that the projection matrix outputs NDC coordinates (-1 to 1) in all 3 axis. So a z position of -1 in NDC coordinate relates to a position on the near clipping plane. A z position of 1 relates to a position on the far clipping plane.


$$anonymous$$y "CalculateUnproject$$anonymous$$atrix" method creates a matrix which does convert viewport coordinates (all axis 0 to 1) into worldspace coordinates. Next thing is you used "$$anonymous$$ultiplyPoint3x4" which does only work for transformation matrices (rotation, translation, scale). If a projection is involved you actually need to use the full homogeneous space and normalize the result. This is automatically done by the $$anonymous$$ultiplyPoint method.


If you have trouble understanding how the projection matrix works, someone asked that already over here.

avatar image Hellium Bunny83 · Feb 01, 2020 at 10:26 PM 0
Share

I saw the question being active the last few days but I didn't think about looking at it.


The comment you have posted below your answer has been very helpful, and I've managed to achieve what I wanted. Thanks a lot Bunny83.

Here is an overview of how I've used your code:

 private void OnDrawGizmosSelected()
 {
     $$anonymous$$atrix4x4 matrix = $$anonymous$$atrix4x4.Ortho(left, right, bottom, top, camera.nearClipPlane, camera.farClipPlane);
     $$anonymous$$atrix4x4 unproject$$anonymous$$atrix = CalculateUnproject$$anonymous$$atrix(matrix, camera.worldToCamera$$anonymous$$atrix);
     Vector3 a = ViewportPointToWorld(new Vector3(0, 0, 1), unproject$$anonymous$$atrix);
     Vector3 b = ViewportPointToWorld(new Vector3(1, 1, 1), unproject$$anonymous$$atrix);
     Gizmos.DrawLine( $$anonymous$$, max );
 }

 private $$anonymous$$atrix4x4 viewToNormalizedDeviceCoordinates$$anonymous$$atrix = $$anonymous$$atrix4x4.Translate(-Vector3.one) * $$anonymous$$atrix4x4.Scale(Vector3.one * 2);

 private $$anonymous$$atrix4x4 CalculateUnproject$$anonymous$$atrix( $$anonymous$$atrix4x4 projection$$anonymous$$atrix, $$anonymous$$atrix4x4 worldToCamera$$anonymous$$atrix )
 {
     $$anonymous$$atrix4x4 matrix = projection$$anonymous$$atrix * worldToCamera$$anonymous$$atrix;
     return matrix.inverse * viewToNormalizedDeviceCoordinates$$anonymous$$atrix;
 }

 private Vector3 ViewportPointToWorld( Vector3 viewportPoint, $$anonymous$$atrix4x4 unproject$$anonymous$$atrix )
 {
     float distanceFromCamera = viewportPoint.z;
     viewportPoint.z = 0;
     var p0 = unproject$$anonymous$$atrix.$$anonymous$$ultiplyPoint(viewportPoint);
     viewportPoint.z = 1;
     var p1 = unproject$$anonymous$$atrix.$$anonymous$$ultiplyPoint(viewportPoint);

     return p0 + ( p1 - p0 ).normalized * distanceFromCamera;
 }

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Need help putting an object at a point based on screen coordinates 1 Answer

mouse position on terrain 1 Answer

Sprite Not Displaying In-game 0 Answers

Indicate with markers the direction of Gameobjects which are outside of the camerafield. 0 Answers

Orthographic camera with rotation and ScreenToWorldPoint 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges