opengl 矩阵投影代码 shade_LookAt、Viewport、Perspective矩阵

6606882bc07ffaec8e88bc3d037ba650.png

LookAt 矩阵

OpenGL本身没有摄像机(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉,而不是场景在移动。

lookat矩阵是由这些东西来定义的:摄像头位置,它看向的方向,以及向上的up方向。由于“OpenGL中我们知道摄像机指向z轴负方向”,所以给图如下:

f02fcb6a2f829e850699c6d9893bab56.png

那么我们知道实际上坐标系的方向是这样的,我们用(eye - center)就能得到z轴的方向,然后我们定义一个向上的方向

,我们可以用
- 向上的方向叉乘z得到x方向,再用
- z方向叉乘x得到y.

8523e72c7793a9d9551b3887908c145b.png

也可以参考这个图:

b8f566c9ddf398c22e2111a664a90e98.png

再根据之前的坐标变换知识,于是我们可以得到lookat矩阵:

  • R - 右向量,也就是相机坐标系x在世界坐标系中的表示
  • U - 上向量,也就是相机坐标系y在世界坐标系中的表示
  • D - 方向向量,也就是相机坐标系z在世界坐标系中的表示
  • P - 相机在世界坐标系中位置

我感觉也可以这样理解,Rotation、Translation其实是相机在世界坐标系中的变换:

其实我们用它来看物体也就是它这个变换的逆变换:

而相机的旋转矩阵的逆是它的转置,平移矩阵的逆也可以在就是把它移回去,这样也跟上面的lookat矩阵一样。写个代码:

void 

Viewport 矩阵

我们再来求另一个常见矩阵,我们现在有模型都在[-1,1]*[-1,1]*[-1,1]正方体中,我们想把它映射到位置[x,x+w]*[y,y+h]*[0,d]中,我们的操作是:

  • 平移:先把[-1,1]*[-1,1]*[-1,1]平移到[0,2]*[0,2]*[0,2]
  • 缩放:[0,2]*[0,2]*[0,2]缩放到[0,1]*[0,1]*[0,1]
  • 缩放:[0,1]*[0,1]*[0,1]缩放到[0,w]*[0,h]*[0,d]
  • 平移:[0,w]*[0,h]*[0,d]移动到[x,x+w]*[y,y+h]*[0,d]

就跟窗口变换十分类似,我们可以来求得这个变换的矩阵:

计算得:

这个矩阵是OpenGL中的Viewport矩阵。

Perspective 矩阵

投影有两种:

正交:

b5e6061f4ed3f6e29021283644f33db0.png

透视:

d6b100166eb5662f1f515c2d2602a0c2.png

我们都知道透视法则-近大远小,就像上图,平行的铁路公路在我们的眼睛里也是会在远处相交的。

1263f5de91ca365966a31fdf08faede9.png

如果我们要将P点投影到 z=0 平面上的 P' 点,camera放在C点(0, 0, c),很容易可以按照比例算出 |AB|/|AC| = |OD|/|OC| 可知: x/(c-z) = x'/c,可知:

所以我们也可以得到投影矩阵:

参考:

  • 摄像机
  • 坐标系统
  • glViewport
  • Perspective projection
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值