透视矩阵的推导(最直观、最深入、最还原,看完请点赞。)

由參数l,r,b,t,n,f定义的透视投影矩阵的推导困惑了我差点儿相同一个多礼拜。这几天差点儿是天天都在思考这个问题。昨天晚上3点多钟我突然醒了,然后我又開始想这个问题,结果最终让我给想通了,于是我赶紧起床把这个思路记在了草稿纸上,还专门照了张照片作证。

透视矩阵的推导(最直观、最深入、最还原,看完请点赞。)
为了解决问题,前几天我专门发了两篇帖子求答案,结果知网上的居然沉掉了。而在csdn上也没有得到答案(质疑有关透视投影矩阵的推导)。

幸亏我自己还是攻克了这个问题。
以下推导的是OpenGL中的透视投影矩阵。
已经知道由參数fovy,aspect,n,f定义的透视投影矩阵为:(有关这块的推导可见《3d graphics for game programming》 2.4.3 derivation of projection matrix,讲得很具体)
P O p e n G L =⎛⎝⎜⎜⎜⎜⎜⎜⎜c o t (f o v y 2 )a s p e c t 0 0 0 0 c o t (f o v y 2 )0 0 0 0 −f +n f −n −1 0 0 −2 n f f −n 0 ⎞⎠⎟⎟⎟⎟⎟⎟⎟
那么再看还有一种投影參数l,r,b,t,n,f,上面矩阵中:
c o t (f o v y 2 )a s p e c t =c o t (f o v x 2 )=2 n r −l ,
c o t (f o v y 2 )=2 n t −b .
由于參数l,r是相应视见空间中x轴的坐标,b,t相应视见空间中y轴的坐标, 假设l=-r而且b=-t。那么由这样的參数定义的透视投影矩阵就是:
P ′O p e n G L =⎛⎝⎜⎜⎜⎜⎜2 n r −l 0 0 0 0 2 n t −b 0 0 0 0 −f +n f −n −1 0 0 −2 n f f −n 0 ⎞⎠⎟⎟⎟⎟⎟
而官方的透视投影矩阵是:
P O p e n G L =⎛⎝⎜⎜⎜⎜⎜⎜2 n r −l 0 0 0 0 2 n t −b 0 0 r +l r −l t +b t −b −f +n f −n −1 0 0 −2 n f f −n 0 ⎞⎠⎟⎟⎟⎟⎟⎟
实际上这个矩阵是由两步转换完毕的, 第一步是进行矩阵P ′O p e n G L 变换,然后进行了*移操作。例如以下:

P O p e n G L =T ×P ′O p e n G L =⎛⎝⎜⎜⎜⎜⎜⎜⎜1 0 0 0 0 1 0 0 0 0 1 0 −r +l r −l −t +b t −b 0 1 ⎞⎠⎟⎟⎟⎟⎟⎟⎟×⎛⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜2 n r −l 0 0 0 0 2 n t −b 0 0 0 0 −f +n f −n −1 0 0 −2 n f f −n 0 ⎞⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟=⎛⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜2 n r −l 0 0 0 0 2 n t −b 0 0 r +l r −l t +b t −b −f +n f −n −1 0 0 −2 n f f −n 0 ⎞⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟

*那些说这个透视投影没有做移这一步操作,我能够100%跟你说你是错的!

**

以下我来解释为什么进行了移操作。
来张示意图:
透视矩阵的推导(最直观、最深入、最还原,看完请点赞。)
这个是视见空间中的示意图。由于存在l≠-r或b≠-t的情况。所以这里我有益没把
裁剪*面中心画在z轴上。

示意图上由红线绘制的立方体才是由l,r,b,t,n,f參数定义的视锥体,当中远裁剪面上的四个点分别相应原点eye经过裁剪面上四个点的延长线与z=-f面的交点,注意这个视锥体是不规则的!

然后图中的标注l’, r’是裁剪面点(l,b,-n)和点(r,b,-n)x轴上的分量在z =−c o t (f o v x 2 )上的投影,l ′=2 l r −l。r ′=2 r r −l。l’和r’的中心值是r +l r −l。同理裁剪面上点(r,b,-n)和点(r,t,-n)y轴上的分量在z =−c o t (f o v y 2 )上的投影。b ′=2 b t −b,t ′=2 t t −b,b’和t’的中心值是t +b t −b。 图中的视锥体通过P ′O p e n G L 透视变换之后得到的是规则的正方体(左下角顶点(2 l r −l ,2 b t −b ,1 ) ,右上角顶点(2 r r −l ,2 t t −b ,−1 )) 。最终要把它转换成cvv(canonical view volume,正规可视化空间)。则须要进行T移转换,也就是移(−r +l r −l ,−t +b t −b ,0 )。得证。

Original: https://www.cnblogs.com/gccbuaa/p/7402623.html
Author: gccbuaa
Title: 透视矩阵的推导(最直观、最深入、最还原,看完请点赞。)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/551792/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 69.修炼爱情

    dfsd posted @2022-09-28 08:46 随遇而安== 阅读(18 ) 评论() 编辑 Original: https://www.cnblogs.com/55z…

    技术杂谈 2023年6月21日
    083
  • DataTable转List<dynamic>

    DataTable转List 最近做的一个项目,MVC+Ado.net。没有ORM很不习惯。找到一个办法,DataTable转List 有过滤字段,和反转过滤字段。 csharp;…

    技术杂谈 2023年5月31日
    069
  • go基于结构的数据序列和还原

    go基于结构的数据序列和还原 go基于结构的数据序列和还原 csharp;gutter:true; // test2 project main.go package main&lt…

    技术杂谈 2023年5月30日
    066
  • Go实现安全双检锁的方法和最佳实践

    不安全的双检锁 从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例? 有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,首次用到的时候才创建实…

    技术杂谈 2023年7月11日
    090
  • MySQL

    数据库 1、为什么需要设计 当数据库比较复杂的时候,我们就需要设计了 糟糕的数据库设计: 数据冗余,浪费空间 数据库插入和删除都会麻烦、异常【屏蔽使用物理外键】 程序的性能差 良好…

    技术杂谈 2023年6月21日
    084
  • Linux&Windows查看IP相关

    ① 查询本机IP 命令行 curl ipinfo.io { "ip": "114.66.43.203", "city":…

    技术杂谈 2023年6月21日
    0115
  • JZ0047:二叉树剪支

    title:二叉树剪支 📃 题目描述 题目链接:二叉树剪支、相同题目 🔔 解题思路 第一种做法:dfs,思考方式是你站在一个点上怎么做,在一个点上,先看左子树是否要删除,再看看右子…

    技术杂谈 2023年7月24日
    070
  • Elasticsearch(5):添加文档

    1 ES数据读写流程 ¶ ES中,每个索引都将被划分为若干分片,每个分片可以有多个副本。这些副本共同组成复制组,复制组中的分片在添加或删除文档时必须保持同步,否则,从一个副本中读取…

    技术杂谈 2023年7月24日
    071
  • (三)underscore.js框架Objects类API学习

    _.keys(object)Retrieve all the names of the object‘s properties. _.keys({one: 1, two…

    技术杂谈 2023年5月31日
    086
  • Sentinel 整合OpenFeign降级

    package com.wsm.stock.controller; import org.springframework.beans.factory.annotation.Valu…

    技术杂谈 2023年5月31日
    070
  • SpringBoot整合多点套路,少走点弯路~

    持续原创输出,点击上方蓝字关注我 前言 Spring Boot 版本 * 找到自动配置类 * 注意 @Conditionalxxx 注解 * 注意 EnableConfigurat…

    技术杂谈 2023年7月24日
    085
  • 原型模式详解

    原型模式 1.1原型模式概述 1.1.1原型模式定义 原型模式(Prototype Pattern)指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象,属于创建型设计模…

    技术杂谈 2023年6月21日
    091
  • 关于计算两日期之间经过多少天的超巧妙算法

    首先声明:本文引自一博主原创博客 昨天呢,刚刚阅读了这个代码,大部分都还可以看懂,有一两个地方属实难懂,但细细思来,方知博主此代码超神奇。简直巧妙至极。 所以来细细解析一下此代码。…

    技术杂谈 2023年7月23日
    0156
  • 面向对象ooDay8

    类中成员的默认访问权限———默认的 接口中成员的默认访问权限——public的 重写接口中的抽象方法时,必须加publi…

    技术杂谈 2023年7月11日
    053
  • 编程语言史话,为什么编程中 1=2?

    考虑以下代码: a = 1 a = a + 1 print(a) 你写代码时候是不是也疑惑过,为什么代码中会有a = a + 1,这个怎么解释?这就不是在说1 = 2么? 这是一个…

    技术杂谈 2023年5月31日
    085
  • 如何有效地开发 Jmix 扩展组件

    扩展组件的概念在使用 Jmix 框架开发中扮演着非常重要的角色。我们将在本文探索什么是扩展组件以及 Jmix Studio 在扩展组件开发和应用程序模块化方面能给开发者带来什么帮助…

    技术杂谈 2023年6月21日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球