【问题标题】:Perspective projection - help me duplicate blender's default scene透视投影 - 帮我复制搅拌机的默认场景
【发布时间】:2015-03-24 11:48:21
【问题描述】:

我目前正在尝试自学透视投影,我的参考资料是这里有关该主题的维基百科页面:http://en.wikipedia.org/wiki/3D_projection#cite_note-3

我的理解是,您将对象投影并旋转并将其转换为“相机空间”,这样您的相机现在被假定为直接向下看 z 轴的原点。 (此矩阵操作来自维基百科页面:http://upload.wikimedia.org/math/5/1/c/51c6a530c7bdd83ed129f7c3f0ff6637.png

然后,您可以使用以下等式将新点投影到 2D 空间:http://upload.wikimedia.org/math/6/8/c/68cb8ee3a483cc4e7ee6553ce58b18ac.png

我可以完美完成的第一步。当然,我编写了自己的矩阵库来做到这一点,但我通过在搅拌机中输入结果并将相机移动到 0,0,0 并检查它是否呈现与默认场景相同来验证它是否吐出了正确的答案。

但是,投影部分是出了问题的地方。

据我所见,我应该采用视野,在搅拌机中默认为 28.842 度,并使用它来计算 wikipedia 调用 ez 的值,通过这样做

ez = 1 / tan(fov / 2);

在这种情况下约为 3.88。

然后我应该为每一点做:

x = (ez / dz) * dx; y = (ez / dz) * dy;

获取 -1 到 1 范围内的 x 和 y 坐标,然后我可以根据屏幕宽度适当缩放。

但是,当我这样做时,我的投影图像在 x 轴上镜像,并且在任何情况下都与立方体混合器渲染不匹配。我做错了什么,我应该怎么做才能获得正确的投影坐标?

我知道你可以用一个矩阵运算完成整个事情,但目前我只是想理解方程式,所以请坚持提出的问题。

【问题讨论】:

  • 我想我们需要看看一些实际的代码。你在使用 OpenGL 吗?即使您的对象的顶点坐标是 3D,OpenGL 和 GLSL 都会创建第 4 个分量 (w) 并期望 4X4 矩阵。实际上,您需要三个矩阵:模型、视图和投影。
  • 视图矩阵由相机(眼睛)的位置、视图方向和相机向上方向组成。投影矩阵定义了截头体,由左、右、上、下、近和远裁剪平面组成。模型矩阵由各种变换组成,如缩放、旋转和平移。您将每个顶点乘以这三个矩阵:投影 * 视图 * 模型 * 顶点。顺便说一句,如果您不使用 OpenGL 或 GLSL,请使用 1.0 作为 w 坐标。
  • 谷歌 glFrustum 和 gluLookAt 看看如何形成投影和视图矩阵。

标签: projection perspective rotational-matrices


【解决方案1】:

根据您在问题中所说的,不清楚您是否遇到了投影矩阵或模型矩阵的问题。

就像我在 cmets 中所说的那样,您可以通过 Google glFrustum 和 gluLookAt 来查看这些矩阵的具体外观。如果您熟悉矩阵数学(看起来确实如此),那么您将了解坐标如何转换为 2D 透视图。

这里是一些示例 OpenGL 代码,用于制作 View 和 Projection Matrices 以及 Model 矩阵,以便绕 Y 轴简单旋转 30 度,以便您了解如何计算进入这些矩阵的组件。

// The Projection Matrix

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
near = -camera.viewPos.z - shapeSize * 0.5;
if (near < 0.00001)
    near = 0.00001;

far = -camera.viewPos.z + shapeSize * 0.5;
if (far < 1.0)
    far = 1.0;
radians = 0.0174532925 * camera.aperture / 2; // half aperture degrees to radians
wd2 = near * tan(radians);
ratio = camera.viewWidth / (float) camera.viewHeight;
if (ratio >= 1.0) {
    left  = -ratio * wd2;
    right = ratio * wd2;
    top = wd2;
    bottom = -wd2;
} else {
    left  = -wd2;
    right = wd2;
    top = wd2 / ratio;
    bottom = -wd2 / ratio;
}

glFrustum (left, right, bottom, top, near, far);

// The View Matrix

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (camera.viewPos.x, camera.viewPos.y, camera.viewPos.z,
           camera.viewPos.x + camera.viewDir.x,
           camera.viewPos.y + camera.viewDir.y,
           camera.viewPos.z + camera.viewDir.z,
           camera.viewUp.x, camera.viewUp.y ,camera.viewUp.z);

// The Model Matrix

glRotatef (30.0, 0.0, 1.0, 0.0);

您会看到 glRotate 实际上进行了四元数旋转(旋转角度加上旋转所围绕的向量)。

您还可以分别绕 X、Y 和 Z 轴旋转。

网络上有很多关于如何形成 4X4 矩阵以进行旋转、平移和缩放的信息。如果您分别执行这些操作,则需要将它们相乘以获得模型矩阵。例如:

如果您有 4X4 矩阵 rotateX、rotateY、rotateZ、translate、scale,您可以通过以下方式形成您的模型矩阵:

模型 = scale * rotateX * rotateZ * rotateY * translate。

形成模型矩阵时,顺序很重要。如果您以不同的顺序进行乘法运算,您将得到不同的结果。

如果你的对象在原点,我怀疑你也想把相机放在原点。

【讨论】:

    猜你喜欢
    • 2018-04-04
    • 1970-01-01
    • 2012-08-19
    • 2021-10-22
    • 2019-05-28
    • 2015-08-23
    • 1970-01-01
    • 2020-01-06
    • 2022-07-17
    相关资源
    最近更新 更多