11.opengl-正射投影和透视投影源码分析

由于OpenGl每次都会将物体都是变换为屏幕上的二维来显示,所以少不了坐标变换(将3D处理在2D上显示),然后并进行裁剪处理(显示范围之外的点都被裁剪掉(Clipped)),默认的可见坐标是-1.0~1.0,假如我们想自己显示投影的部分,那么就需要投影矩阵,通过投影矩阵可以创建一个观察箱(Viewing Box),又称为平截头体(Frustum),那么所有出现在观察箱里的顶点都会显示在屏幕上,创建一个投影矩阵有两种不同方法:

正射投影矩阵(Orthographic Projection Matrix)或一个透视投影矩阵(Perspective Projection Matrix).

1.正射投影(orthographic projection matrix)

正射投影对应的qt中函数是:

void QMatrix4x4::ortho(float left, float right, 
                       float bottom, float top, 
                       float nearPlane, float farPlane)

// left right, bottom, top : 设置观察箱(平截头体)的上下左右坐标
// nearPlane: 设置近平面的距离
// farPlane: 设置远平面的距离

对应如下图所示:

初始化好投影矩阵后,会将处于这些xyz值范围内的坐标变换为标准化设备坐标,对应的源码如下所示:

如上图所示,可以看到将转换规则以一个系数存储在矩阵中,当乘上原本的标准坐标向量时,就会将标准坐标转为标准化设备坐标,而对于w分量部分(矩阵最后一行)依然是[0 0 0 1],所以会导致无论物体距离相机多远投影后的物体大小尺寸不变.如下图所示:

使用透视投影的话,远处的顶点看起来比较小,而在正射投影中每个顶点距离观察者的距离都是一样的。

2.透视投影

使用透视投影,会比正射投影更加真实(投影中心无变形,离中心越远变形越大)

透视投影通过w分量来实现,离观察者越则w分量越大,然后顶点坐标的每个分量都会去除以它的w分量(所以越远,则顶点坐标越小):

所以我们之前学习的坐标向量都是vec4,因为通过w分量才能帮我们进行透视投影.

透视投影对应的qt中函数是:

void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane)

// verticalAngle: 垂直角度(也就是裁剪窗口的高度),值越大,那么物体越小

// aspectRatio: 横纵比(由视口的宽除以高所得),值越大则越宽值,比如宽高为100X50,那么就等于2

// nearPlane: 设置近平面的距离(一般设置为0.1)

// farPlane: 设置远平面的距离(一般设置为100)

源代码如下所示:

可以看到对于w分量部分(矩阵最后一行)是[0 0 -1 0],假如z向量有值的话会乘以(-1).得到的w分量将会有值的,通过透视除法后将会导致坐标越小,接下来我们便来测试一下.

3.正射投影和透视投影测试

测试代码如下所示:

    Vector4D vec(1,2,100,1);

    QMatrix4x4 projection1;
    projection1.ortho(10,20,0,10,10,100);
    qDebug()<<projection1<<projection1*vec;

    QMatrix4x4 projection2;
    projection2.perspective(10,20,0.1,100);
    qDebug()<<projection2<<projection2*vec;

运行打印:

可以看到对于z为100的物体,通过透视投影转换后得到的坐标的z值是-100。然后当顶点变换到裁剪空间时,会执行透视除法,从而导致顶点坐标很小.

而对于正射投影的话,转换出来的向量z值始终为1. 所以正射投影不支持透视除法.

未完待续,下章就在3D场景中使用投影矩阵.

本专栏opengl技术交流群:929155430

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诺谦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值