gluperspective()/glm :: perspective()工作中的附近/远剪掉飞机如何工作



我有一个问题,即标准透视投影矩阵如何工作,从 gluPerspective()glm::perspective()获得的质量。具体来说,我想知道近/远的剪裁飞机。

i的印象是,在转换了一个透视矩阵的点后,映射到z值的近夹平面上的对象,以及映射到z值的远夹平面附近的对象。p>例如,可以说您的摄像头位于原点,朝向正Z轴的方向,近夹子平面在1.0处,远夹平面设置为2.0。然后,我希望将"世界" Z坐标在1.0到2.0之间的事物将被转换为预测坐标在-1.0和1.0之间。

换句话说,我希望此C 代码:

#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
void print_vec(vec4 pnt) {
    std::cout << "(" << pnt.x << ", " << pnt.y << ", " << pnt.z << ")" << "n";
}
int main() {
    mat4x4 view = lookAt(
            vec3(0.0f, 0.0f, 0.0f),   // eye at origin
            vec3(0.0f, 0.0f, 1.0f),   // looking towards +Z
            vec3(0.0f, 1.0f, 0.0f));  // up is +Y
    mat4x4 projection = perspective(
            radians(90.0f),  // field of view
            1.0f,            // aspect ratio
            1.0f,            // near clipping plane
            2.0f);           // far clipping plane
    // transformation matrix for world coordinates
    mat4x4 vp = projection * view; 
    // points (0,0,1), (0,0,1.5) and (0,0,2) in homogeneous coordinates
    print_vec(vp * vec4(0.0f, 0.0f, 1.0f, 1.0f));
    print_vec(vp * vec4(0.0f, 0.0f, 1.5f, 1.0f));
    print_vec(vp * vec4(0.0f, 0.0f, 2.0f, 1.0f));
}

打印出此

(0, 0, -1)
(0, 0, 0)
(0, 0, 1)

但事实并非如此。它打印出来:

(0, 0, -1)
(0, 0, 0.5)
(0, 0, 2)

我不明白为什么。我希望的像我期望的那样的近夹平面项目,但是在投射时,恰好在飞机之间的中途靠近后部,而远夹平面上的点完全在[-1,1]之外。

我认为有一些我只是缺少的基本数学东西,所以这就是为什么我要问你好研究员。

(顺便说一句,我正在处理的事情实际上是用Rust编写的,而不是C ,但是我切换到C 进行此测试,以确保Rust Expartionation或其他内容没有错误。)

但事实并非如此。它打印出来:

(0, 0, -1)
(0, 0, 0.5)
(0, 0, 2)

这是错误的,因为结果不是vec3类型,它是类型vec4的均匀坐标:

(0, 0, -1, 1)
(0, 0, 0.5, 1.5)
(0, 0, 2, 2)

您必须进行视角鸿沟,然后您将获得预期的结果:

(0/1,   0/1,   -1/1)
(0/1.5, 0/1.5,  0.5/1.5)
(0/2,   0/2,    2/2)

最新更新