世界到Unity中的屏幕坐标

时间:2015-07-03 09:38:18

标签: math unity3d

对于我当前的项目,有必要计算Unity中世界空间中给定点的屏幕坐标。

我使用this tutorial来编写一个方法来实现这一目的。

经过一些调试后,x和y屏幕坐标是正确的,但我的z坐标看起来不对,我还有一些问题:

static public Vector3 convertWorldToScreenCoordinates (Vector3 point, PhotoData photoData)
{   
    // get the camera
    Camera camera = GameObject.Find (photoData.cameraName).camera;

    /*
    * 1 convert P_world to P_camera
    */
    Vector4 pointInCameraCoodinates = convertWorldToCameraCoordinates (point, photoData);


    /*
    * 2 convert P_camera to P_clipped
    */
    Vector4 pointInClipCoordinates = camera.projectionMatrix * pointInCameraCoodinates;

    /*
    * 3 convert P_clipped to P_ndc 
    * Normalized Device Coordinates
    */
    Vector3 pointInNdc = pointInClipCoordinates / pointInClipCoordinates.w;


    /*
    * 4 convert P_ndc to P_screen
    */
    Vector3 pointInScreenCoordinates;
    pointInScreenCoordinates.x = camera.pixelWidth / 2.0f * (pointInNdc.x + 1);
    pointInScreenCoordinates.y = camera.pixelHeight / 2.0f * (pointInNdc.y + 1);
    pointInScreenCoordinates.z = ((camera.farClipPlane - camera.nearClipPlane) * pointInNdc.z + (camera.farClipPlane + camera.nearClipPlane)) / 2.0f;


    // return screencoordinates
    return pointInScreenCoordinates;        
}

PhotoData是一个类,包含有关相机的一些信息。这里的重要部分是我可以访问相机。

static public Vector4 convertWorldToCameraCoordinates (Vector3 point, PhotoData photoData)
{
    // translate the point by the negative camera-offset 
    //and convert to Vector4
    Vector4 translatedPoint = point - photoData.cameraPosition;
    // by default translatedPoint.w is 0
    translatedPoint.w = 1.0f;

    // create transformation matrix
    Matrix4x4 transformationMatrix = Matrix4x4.identity;

    transformationMatrix.SetRow (0, photoData.camRight);
    transformationMatrix.SetRow (1, photoData.camUp);
    transformationMatrix.SetRow (2, - photoData.camForward);            

    Vector4 transformedPoint = transformationMatrix * translatedPoint;

    return transformedPoint;
}

首先,教程提到,在计算ndc值之后,“值的范围现在在所有3个轴中从-1到1归一化”。在我的情况下这是不正确的,我不明白我做错了什么。

我的第二个问题是,pointInClipCoordinates.z < 0是否意味着世界点落后于我的相机?

到目前为止的最后一个问题是为什么我必须使用- photoData.camForward

//编辑:更新的代码+问题

1 个答案:

答案 0 :(得分:1)

对于编辑器脚本,使用HandleUtility.WorldToGUIPoint(自Unity3D 4.12起可用)将世界空间点转换为2D GUI位置。

相关问题