C# 类似正交变换的透视投影矩阵变换

C# 类似正交变换的透视投影矩阵变换,c#,math,matrix,C#,Math,Matrix,假设我有一个不在(0,0,0)中的点和一个正看着(0,0,0)的透视相机。 据我所知,如果我沿着z轴移动透视相机,屏幕上的点也应该移动。相机越远,点在屏幕坐标中应越靠近(0,0) 在我的C#程序中,摄像机的移动根本不会影响屏幕坐标(x,y)。它只会像正交摄影机一样更改z坐标。以下是最简单的示例: Vector3 v = new Vector3(3.0f); // Move camera z to -10 from the center Matri

假设我有一个不在(0,0,0)中的点和一个正看着(0,0,0)的透视相机。 据我所知,如果我沿着z轴移动透视相机,屏幕上的点也应该移动。相机越远,点在屏幕坐标中应越靠近(0,0)

在我的C#程序中,摄像机的移动根本不会影响屏幕坐标(x,y)。它只会像正交摄影机一样更改z坐标。以下是最简单的示例:

        Vector3 v = new Vector3(3.0f);
        // Move camera z to  -10 from the center
        Matrix4x4 viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -10.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
        Matrix4x4 projectionMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 3.0f, 1.0f, 0.1f, 100.0f);
        Vector3 v1 = Vector3.Transform(v, viewMatrix * projectionMatrix);
        Console.WriteLine(v1); //<-5.1961527, 5.1961527, 12.912912>
        // Move camera z to -1 from the center
        viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -1.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
        Vector3 v2 = Vector3.Transform(v, viewMatrix * projectionMatrix);
        Console.WriteLine(v2); //<-5.1961527, 5.1961527, 3.903904>
vector3v=新的Vector3(3.0f);
//将摄影机z从中心移动到-10
Matrix4x4 viewMatrix=Matrix4x4.CreateLookAt(新矢量3(0.0f,0.0f,-10.0f),新矢量3(0.0f,0.0f,0.0f),新矢量3(0.0f,1.0f,0.0f));
Matrix4x4 projectionMatrix=Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI/3.0f、1.0f、0.1f、100.0f);
Vector3 v1=Vector3.变换(v,viewMatrix*projectionMatrix);
控制台写入线(v1)//
//将摄影机z从中心移动到-1
viewMatrix=Matrix4x4.CreateLookAt(新矢量3(0.0f,0.0f,-1.0f),新矢量3(0.0f,0.0f,0.0f),新矢量3(0.0f,1.0f,0.0f));
Vector3 v2=Vector3.变换(v,viewMatrix*projectionMatrix);
控制台写入线(v2)//

我的推理有什么错误?

也许投影坐标的W不是1

在顶点着色器中,返回的W表示点或向量。如果为1,则为点。但由于某些原因,顶点着色器会自动将XYZ除以W。因此,顶点着色器不需要显式将W设置为1,并且几乎所有三维数学库都会将W作为除数而不是1返回


如果要获得正确的投影坐标,请手动分割
Vector4.Transform()
并将XYZ除以W.

可能投影坐标的W不是1

在顶点着色器中,返回的W表示点或向量。如果为1,则为点。但由于某些原因,顶点着色器会自动将XYZ除以W。因此,顶点着色器不需要显式将W设置为1,并且几乎所有三维数学库都会将W作为除数而不是1返回


如果要获得正确的投影坐标,请手动分割
Vector4.Transform()
并将XYZ除以W。

可能投影坐标的W不是1
Vector4.Transform()
并将XYZ除以W,即是。出于某种原因,我认为Vector3.Transform更聪明一些。这应该是一个答案。我发布了一个包含更多信息的答案。如果你解决了这个问题,请标出答案。也许投影坐标的W不是1
Vector4.Transform()
并将XYZ除以W,即是。出于某种原因,我认为Vector3.Transform更聪明一些。这应该是一个答案。我发布了一个包含更多信息的答案。如果你解决了这个问题,请标出答案。