【发布时间】:2015-07-03 09:38:17
【问题描述】:
对于我当前的项目,我必须在 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?
// 编辑:更新代码+问题
【问题讨论】:
-
这部分我要自己写。但是谢谢你提到它!我使用这种方法来验证我的结果。
-
为什么要除以 abs(w)?只需除以 w