0

几天前,我决定开始 3D 编程并遇到透视投影。我使用以下代码来获取矩阵:

public static Matrix3D ProjectionMatrix(double angle, double aspect, double near, double far)
{
    double size = near * Math.Tan(MathUtils.DegreeToRadian(angle) / 2.0);
    double left = -size, right = size, bottom = -size / aspect, top = size / aspect;
    Matrix3D m = new Matrix3D(new double[,] {
    {2*near/(right-left),0,(right + left)/(right - left),0},
    {0,2*near/(top-bottom),(top+bottom)/(top-bottom),0},
    {0,0,-(far+near)/(far-near),-(2 * far * near) / (far - near)},
    {0,0,-1,0}
    });
    return m;
}

我对相机使用以下代码:

Matrix3D Camera
{
    get
    {
        Vector3D cameraZAxis = -this.LookDirection;
        cameraZAxis.Normalize();

        Vector3D cameraXAxis = Vector3D.CrossProduct(this.UpDirection, cameraZAxis);
        cameraXAxis.Normalize();

        Vector3D cameraYAxis = Vector3D.CrossProduct(cameraZAxis, cameraXAxis);

        Vector3D cameraPosition = (Vector3D)this.Position;
        double offsetX = -Vector3D.DotProduct(cameraXAxis, cameraPosition);
        double offsetY = -Vector3D.DotProduct(cameraYAxis, cameraPosition);
        double offsetZ = -Vector3D.DotProduct(cameraZAxis, cameraPosition);

        return new Matrix3D(new double[,]{{cameraXAxis.X, cameraYAxis.X, cameraZAxis.X, 0},
                            {cameraXAxis.Y, cameraYAxis.Y, cameraZAxis.Y, 0},
                            {cameraXAxis.Z, cameraYAxis.Z, cameraZAxis.Z, 0},
                            {offsetX, offsetY, offsetZ, 1}});
    }
}

但是,我不知道如何获得模型或世界矩阵,还有以前的代码有什么问题吗?

4

1 回答 1

0

矩阵用于将对象从一个“空间”转换为另一个。想象一个立方体模型,模型中心为 0,0,0,每个角的范围为 5。现在要将其转换为您的世界,您将应用 Worldmatrix 进行转换,将这些模型坐标放入您的世界。

例如,应该将模型“移动”到 5、5、5 的平移。现在只需考虑将此位置添加到模型及其所有点,现在这些新坐标称为“在世界空间中”。现在模型通过您的世界矩阵放置在世界中的位置 5,5,5(您以前的模型中心现在驻留在您的世界中的这个位置)。

视图矩阵有点难以理解,但最容易理解的是“我们不能移动相机,所以我们将所有对象都向相反的方向移动,所以看起来我们移动了相机”。这听起来很难,但实际上它就像从模型空间转换到世界空间一样。

现在我们从世界空间转换到视图空间。最后,我们需要把它放到屏幕上。显然你的屏幕是 2D 的,你仍然有一个 3D 场景,现在你需要一种方法来将你的 3D 对象转换到你的视图空间中。这可以通过不同类型的投影来实现。两个重要的是正交投影和透视投影。事实上,这使用了 Z 分量(我们在 2D 表面上没有它,比如屏幕)和屏幕分辨率将我们的可见世界“投影”到我们的屏幕空间中。

所有这些都可以使用矩阵轻松完成。每次转型都有一个良好的开端。公平地说,您不需要任何数据,您可以直接在屏幕空间中提供数据,但这并不实用。例如,如果您不需要 World 矩阵(如果您的模型经过建模以便可以直接使用,则会发生这种情况),您将使用 Matrix.Identity ,它可以粗略地解释为将数字乘以 1,从而为您提供相同的号码。视图的单位矩阵也就像将相机放置在世界上的 0,0,0 并向下看 Z 轴(哪个轴很大程度上取决于您使用的坐标系)

要获得着色器的最终矩阵,通常将所有这些矩阵(或通过乘法组合的矩阵)传递给着色器。如果您使用固定功能管道,通常有提供它们的方法。投影通常是固定的,但可以更改以应用一些视觉效果,例如缩放狙击步枪或鱼眼效果。相机矩阵当然是用来移动和旋转相机的。世界矩阵用于在场景中定位对象、移动玩家、旋转门等。

免责声明:这就是我自己理解整个事情的方式,所以这绝不是一个数学上的正确解释,但也许它对 OP 有任何帮助。

为了更好地理解整个主题,您可以阅读内容。

于 2012-06-21T14:04:36.357 回答