Search Unity

get screen position using mvp matrix in script

Discussion in 'Shaders' started by astrokoo, May 5, 2013.

  1. astrokoo

    astrokoo

    Joined:
    Nov 17, 2011
    Posts:
    6
    hi :)

    i'm studying about projection matrix. i think mvp * localModel position is screen position

    but when i try below code it display difference result.

    what am i wrong?

    can anyone explain this would be thankful.

    Matrix4x4 m = transform.localToWorldMatrix;
    Matrix4x4 v = Camera.mainCamera.worldToCameraMatrix;
    Matrix4x4 p = Camera.mainCamera.projectionMatrix;

    Matrix4x4 MVP = p*v*m;

    Mesh mesh = gameObject.GetComponent<MeshFilter>().mesh;
    Vector3[] vertices = mesh.vertices;

    int i = 0;
    while (i < vertices.Length) {

    print(MVP.MultiplyPoint(vertices)); // <-- i expect this result same as WorldToScreenPoint but it's not!
    print(Camera.mainCamera.projectionMatrix.MultiplyPoint(vertices));
    print(Camera.mainCamera.WorldToScreenPoint(vertices));
    i++;
    }
     
  2. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    try m*v*p
     
  3. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Vectors are right-multiplied with transformation matrices, so P*V*M*vertex is correct.

    Astrokoo, have you looked at this question?
     
  4. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    After vertex transformed by mvp, it is in clip space ,not in screen space,either(-1,1) nor (screen.width,screen.height)
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Yes, this is an important observation too. MVP takes a vertex from object space to clip space, whose (x, y) coordinates are in (-1, 1). Rasterization to screen space in a shader is a hidden step between your vertex and fragment programs. You will have to scale and bias the resulting value if you want to get to screen space ((0, 0), (Screen.width, height)), or viewport space (0, 1).
     
    world.st likes this.
  6. teexit

    teexit

    Joined:
    Jul 5, 2012
    Posts:
    26
    I have same problem.

    why MVP.MultiplyPoint(vertices) is not same as WorldToScreenPoint?
     
  7. world.st

    world.st

    Joined:
    Jul 15, 2015
    Posts:
    3
    You should use this:


    Matrix4x4 matrix = _3dCamera.projectionMatrix * _3dCamera.worldToCameraMatrix;
    Vector3 screenPos = matrix.MultiplyPoint(newObj.transform.position);

    // (-1, 1)'s clip => (0 ,1)'s viewport
    screenPos= new Vector3(screenPos.x + 1f, screenPos.y + 1f, screenPos.z + 1f) / 2f;

    // viewport => screen
    screenPos = new Vector3(screenPos.x * Screen.width, screenPos.y * Screen.height, screenPos.z);
     
    GilCat likes this.