我想将3d位置转换为2d屏幕位置.我看了一个类似的问题:将3D点投影到2D屏幕坐标,但我完全不了解它.我想为了计算2d位置我需要投影矩阵,但我不知道如何使用它,除了将点转换为位置坐标空间.此外,cam.FieldOfView是否等于OpenGL中的farZ?
有人可以帮我完成这个功能.参数是否足以计算2d位置?Pos已经是相对于相机位置的矢量.
Vector2* convert(Vector3& pos, Matrix4& projectionMatrix, int screenWidth, int screenHeight)
{
float ratio = screenWidth / screenHeight;
...
screenX = screenWidth * ( 1.0f - screenX);
screenY = screenHeight * ( 1.0f - screenY);
return new Vector2(screenX, screenY);
}
Run Code Online (Sandbox Code Playgroud)
Jea*_*ean 10
在我看来会是这样的:
Vector2 Convert(Vector3 pos, const Matrix& viewMatrix, const Matrix& projectionMatrix, int screenWidth, int screenHeight)
{
pos = Vector3::Transform(pos, viewMatrix);
pos = Vector3::Transform(pos, projectionMatrix);
pos.X = screenWidth*(pos.X + 1.0)/2.0;
pos.Y = screenHeight * (1.0 - ((pos.Y + 1.0) / 2.0));
return Vector2(pos.X, pos.Y);
}
Run Code Online (Sandbox Code Playgroud)
我们在这里做的只是通过两个转换矩阵传递Vector:视图,然后是投影.在投影之后,你得到一个Y和X在-1和1之间的向量.我们进行适当的变换以获得真实的像素坐标并返回一个新的Vector2.请注意,'pos'的Z分量还在屏幕空间中存储功能结束时的点的深度.
您需要"视图"矩阵,因为它定义了摄像机的位置和旋转位置.投影仅定义3D空间在2D空间上"展平"的方式.
视野不是farZ.投影矩阵有一些参数,其中包括:
除了数学问题,您可以直接使用Vector2而不是堆分配(返回指针).Vector2是一个轻量级结构,指针很可能在这种情况下引起头痛(你要删除它的位置,依此类推).还要注意我使用'const'引用,因为除了vector之外我们不修改它们.对于这个我们想要一个本地副本,这就是为什么它根本不是一个参考.
以前的代码仅在您不进行任何旋转时才起作用(例如GL.Rotate(rotation_x, 1.0, 0.0, 0.0)).但如果你这里做的是代码:
private Vector2 Convert(Vector3 pos, Matrix4 viewMatrix, Matrix4 projectionMatrix, int screenWidth, int screenHeight)
{
pos = Vector3.Transform(pos, viewMatrix);
pos = Vector3.Transform(pos, projectionMatrix);
pos.X /= pos.Z;
pos.Y /= pos.Z;
pos.X = (pos.X + 1) * screenWidth / 2;
pos.Y = (pos.Y + 1) * screenHeight / 2;
return new Vector2(pos.X, pos.Y);
}
Run Code Online (Sandbox Code Playgroud)