当前位置: 首页 > news >正文

观察矩阵(View Matrix)、投影矩阵(Projection Matrix)、视口矩阵(Window Matrix)及VPM矩阵及它们之间的关系

      V表示摄像机的观察矩阵(View Matrix),它的作用是把对象从世界坐标系变换到摄像机坐标系。因此,对于世界坐标系下的坐标值worldCoord(x0, y0, z0),如果希望使用观察矩阵VM将其变换为摄像机坐标系下的坐标值localCoord(x’, y’, z’),则有:

localCoord = worldCoord * VM

此外,观察矩阵可理解为“摄像机在世界坐标系下的位姿矩阵的逆矩阵”,也可理解为"世界坐标系在摄像机坐标系下的位姿矩阵。因此Camera 类也专门提供了getInverseViewMatrix 这样一个函数,它的实际意义是表示摄像机在世界坐标系下的位置;而Camera 类的getViewMatrix函数则表示世界坐标系下的某个物体的位姿矩阵变换到以摄像机坐标系为基准下的矩阵。这个有点绕,具体参见如下博文:

浅谈在操控器类中,为何要通过osgGA::CameraManipulator的逆矩阵改变视点位置

        P 表示投影矩阵(Projection Matrix),当我们使用 setProjectionMatrixAsPerspective 之类的函数设置摄像机的投影矩阵时,我们相当于创建了一个视截锥体,并尝试把包含在其中的场景对象投影到镜头平面上来。如果投影矩阵为PM,而得到的投影坐标为projCoord(x”, y”, z”)的话,那么:

projCoord = localCoord * PM

      W表示视口矩阵(Window Matrix),它负责把投影坐标变换到指定的二维视口(viewport)中去, 对于视口矩阵WM,通过下面的公式可以得到最终的窗口坐标windowCoord(x”', y”', 0):

windowCoord = projCoord * WM

将所有的公式整合之后,得到:

windowCoord = worldCoord * VM * PM * WM

而这个所谓的窗口坐标windowCoord,实际上也就是世界坐标系下的坐标值worldCoord 在指定的摄像机视口中(也就是我们的屏幕上)对应的平面位置。怎么样,不知不觉中,我 们已经实现了gluProject函数所完成的功能了。记:

VPW =  VM * PM * WM

则:

windowCoord = worldCoord * VPM

 对上式左右两边乘以VPM的逆,如下:

即反转这三个步骤就可以得到视口中指定位置所对应的世界坐标了(也就是gluUnProject的工作)即:

参考资料

【1】:王锐 .《最长的一帧》 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 微服务-初级篇
  • mac|Mac压缩与解压缩
  • 在程序中引用cuda.memory函数监控GPU内存
  • Linux系统编程——线程控制
  • 聚道云赋能,财务流程大提速,NC凭证对接一键通!
  • js面试题2024
  • tessy 单元测试:小白入门指导手册
  • DAY2:插件学习
  • 【Word】快速对齐目录
  • [Spring] SpringBoot基本配置与快速上手
  • QImage 的图片可以直接显示吗
  • python调用串口收发数据
  • 用WPF实现的窗体是怎么运行的?
  • 反向代理概念
  • app: 和 android:的区别
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • HomeBrew常规使用教程
  • JavaScript异步流程控制的前世今生
  • js中forEach回调同异步问题
  • rc-form之最单纯情况
  • Redis 中的布隆过滤器
  • Selenium实战教程系列(二)---元素定位
  • Travix是如何部署应用程序到Kubernetes上的
  • 彻底搞懂浏览器Event-loop
  • 简析gRPC client 连接管理
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • (02)vite环境变量配置
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (4.10~4.16)
  • (LeetCode C++)盛最多水的容器
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (ros//EnvironmentVariables)ros环境变量
  • (分布式缓存)Redis哨兵
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (三)SvelteKit教程:layout 文件
  • (四)进入MySQL 【事务】
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (循环依赖问题)学习spring的第九天
  • (转)IOS中获取各种文件的目录路径的方法
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .env.development、.env.production、.env.staging
  • .gitignore文件忽略的内容不生效问题解决
  • .Net Core与存储过程(一)
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET学习全景图
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • /var/lib/dpkg/lock 锁定问题
  • @JsonFormat与@DateTimeFormat注解的使用
  • @ohos.systemParameterEnhance系统参数接口调用:控制设备硬件(执行shell命令方式)
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [Angular] 笔记 20:NgContent