【OpenGL】透视投影矩阵推导

项目场景:

  • 系统:ubuntu
  • glad + glfw + opengl3.3
    复习games101MVP变换,在使用OpenGL检验推导透视投影矩阵时,发现得出结果的Z坐标与把不符合目标预期。可以看到下面代码,四个矩形从前到后的顺序应该是RGB然后才到粉色,可是实际是反过来的。
    【OpenGL】透视投影矩阵推导_第1张图片

问题描述

为什么缩放Z轴需要为负数(红圈的地方,已经加入负号,最终效果正确)。
【OpenGL】透视投影矩阵推导_第2张图片


原因分析:

为什么会这样呢?在纸上反复计算了半天后,刷手机看机了罗斯大佬的视频
探秘三维透视投影 - 齐次坐标的妙用,才发现原来OpenGL转NDC时,默认是近平面映射到-1,远平面映射到1,我大呼白费力气,原来一开始就错了,难怪算半天没发现问题,原来不是算错了。
后来查看OpenGL wiki glDepthRange 、glDepthFunc和glClearDepth。

Parameters

nearVal
Specifies the mapping of the near clipping plane to window coordinates. The initial value is 0.


farVal
Specifies the mapping of the far clipping plane to window coordinates. The initial value is 1.


Description
After clipping and division by w, depth coordinates range from −1 to 1, corresponding to the near and far clipping planes. glDepthRange specifies a linear mapping of the normalized depth coordinates in this range to window depth coordinates. Regardless of the actual depth buffer implementation, window coordinate depth values are treated as though they range from 0 through 1 (like color components). Thus, the values accepted by glDepthRange are both clamped to this range before they are accepted.

The setting of (0,1) maps the near plane to 0 and the far plane to 1. With this mapping, the depth buffer range is fully utilized.

这里意思是
【OpenGL】透视投影矩阵推导_第3张图片
压缩的空间可以自定义,默认(0,1),OpenGL深度测试默认比小,每个像素深度值默认为1。
这也就是为什么默认值OpenGL要在透视投影变换中把Z轴翻转。
如果不想翻转,只需设置

glDepthFunc(GL_GREATER);    // 设置为比大
glClearDepth(0.0f);         // 设置默认深度值为0

修改后效果:
【OpenGL】透视投影矩阵推导_第4张图片
参考代码:OpenGL_Learn

你可能感兴趣的:(图形学,矩阵,线性代数)