GAMES101-现代计算机图形学入门-闫令琪 - lecture4 观测变换(viewing transformation) - 课后笔记

本文主要是介绍GAMES101-现代计算机图形学入门-闫令琪 - lecture4 观测变换(viewing transformation) - 课后笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

观测变换(Viewing transformation)

  • 视图 / 相机变换(View / Camera transformation)
  • 投影变换(Projection transformation)
    • 正交投影(Orthographic projection)
    • 透视投影(Perspective projection)

视图/相机变换(View / Camera transformation)

什么是视图变换?

思考下如何去拍摄一张照片:

  • 找到一个好地方,并且调整人的姿势,(只对模型进行了变换(model transform))
  • 调整一个合适的角度,放置摄像机(view transformation)
  • 茄子!(将3d转化为2d,投影变换(projection transformation))

图形就是按照上面的步骤进行变换,最终获得屏幕上的2D图像,这之中进行了三次变换,分别是模型变换(model transformation)、视图变换(view transformation)、投影变换(projection transformation),简称MVP ,这节中主要说视图变换。

视图变换操作的主要对象是相机,然后其他的物体跟着变换。

如何实现一个视图变换?

视图变换是对摄像机进行操作,所以需要先定义一个Camera,定义一个Camera需要:

  • Camera的位置 e (Position)
  • Camera的观察方向 g (Look-at / gaze direction),
  • Camera的上方向 t(Up direction),上方向用于固定摄像机的角度,如t指向正上方,那么摄像机就是正的,若t指向斜上方,那么Camera拍出来的图片就是斜的
  • Camera的右方向 g × t

在这里插入图片描述
在这里插入图片描述

如果把Camera看作空间中的一个物体,若将Camera和其他的物体同时进行移动(进行同一种的位移变换),那么其他的物体和Camera就会是一种相对静止则Camera中显示的画面就永远不会发生改变,所以要希望能够通过Camera观察不同的物体以及转换视角,必须要让Camera和空间中的其他物体实现相对运动。

只移动物体或者只移动Camera,最后可能都会得到同一个结果。那么既然这样的话,不如永远把Camera固定到原点的位置,并且Up方向指向y轴方向,Look-at方向指向-z轴的方向。这样就认为其他所有的物体在移动,而相机并不移动,为什么这么做?老师说这是大家约定俗成的一个东西。其实因为相机放在(0,0,0)的位置有很多的好处,相机沿着-z看也会有很多的好处。所以这个约定的相机位置就是一个标准位置

那么怎么操作才能把相机放到原点的位置,并且Up指向y方向,Look-at指向z方向?

相机到达这个标准位置,需要经过平移和变换,那么就用一个变换矩阵来完成相机到原点的过程。该矩阵为:

在这里插入图片描述

那么这个M(view)矩阵在数学上怎么实现?将下面多个变化叠加,最终可以得到M(view)矩阵.

  • 先将Camera的position变换到原点(origin)
  • 将g旋转到-z轴方向
  • 将t旋转到y轴方向
  • 将g×t旋转到x轴方向

在这里插入图片描述

M(view)矩阵的具体实现:

将M(view)矩阵分解为R(view)和T(view)两种变换矩阵,其中T(view)为位移矩阵,将Camera的position移动到原点,R(view)为旋转矩阵,将Camera的几个方向轴旋转到坐标系的位置。

在这里插入图片描述

T(view)矩阵,将Camera的position移动到原点,即将(xe,ye,ze)移动到(0,0,0),则x,y,z上的位移量分别为-xe,-ye,-ze。

在这里插入图片描述

R(view)矩阵要做的事就是将g旋转到-z轴,t旋转到Y轴,(g × t)旋转到x轴。如果这样直接旋转太麻烦,-z轴的方向向量为(0,0,-1),y轴的方向向量为(0,1,0),x轴的方向向量为(1,0,0),明显可以看出,从-z旋转到g,从y旋转到t,从x轴旋转到(g×t)更为简单,这个旋转矩阵为:
在这里插入图片描述

再求这个矩阵的逆矩阵,即逆变换,就可以得到Camera的三个方向旋转到坐标系的三个轴的变换矩阵。因为旋转矩阵都是正交矩阵,所以其逆矩阵 = 转置矩阵。

在这里插入图片描述

得到了以上的两个变换矩阵后,就可以将Camera的位置设置在原点,并以-z轴为look-at方向,以y轴为up方向。就可以认为Camera是始终不动,变换的一直是Camera以外的其他的物体

相机/视图变换总结

投影变换(Projection transformation)

在图形学中,投影就是将3D的图形投影到2D的平面上,即将三维物体转换成能在能在屏幕上显示的二维图像。

投影变换分为正交投影和透视投影

在这里插入图片描述

左图为正交投影,右图为透视投影。透视投影进大远小,更符合人眼的观察效果;正交投影不具有进大远小的性质,正交投影是假设Camera位于无限远的位置,投影出来的物体不论近处还是远处,大小都是一样大,更适用于工程制图。具体情况如下所示:
在这里插入图片描述

左图为透视投影,透视投影的近平面和远平面的大小不同,会将平截头体内部的物体投影到近平面上(绿球在外面,所以没有投影进来),并且离近平面(near clip plane)近的物体较大,远的物体的投影较小。右图为正交投影,而正交投影则是将正方体内物体投影到近平面上,假设Camera在无限远处,那么所有的投影都是以平行光的方式进行投影到近平面上,所以不具有近大远小的效果。(只有在近平面(near clip plane)和远平面(far clip plane)内的物体才能被投影到近平面上)。

正交(射)投影(Orthographic Projection)

正交投影是把Camera固定在原点上,look-at方向为-z轴,up方向为y轴,如果要对物体进行正交投影,只需要将三维坐标中的z坐标直接丢弃,就能够得到投影的结果,如图所示,投影平面为z = 0,直接丢弃z坐标或者直接令z坐标为0,就可以得到投影的效果。

在这里插入图片描述

正交投影最后会被缩放到一个[-1,1]的区间范围内,即所有的点的坐标的分量都是在[-1,1]之间的,如果在范围之外则会缩放到[-1,1]之间,这是一个约定俗成的规定。

但是正交投影无法区分前后关系,如上图所示,得到的投影面如下:
在这里插入图片描述

你并不能判断E在前面还是方块在前面。

那么,如果我有一个立方体,我应该如把它转换到[-1,1]之间?

在坐标系统,使用六个数即可定义个立方体(如x=1代表一个面,x=-1代表一个面,六个数定义6个面,包围起来的立体就是立方体),用 l(left) , r(righit) , b(bottom) , t(top) , f(far) , n(near)六个数定义一个立方体.

在这里插入图片描述

最右边的立方体经过位移,缩放,最终投影的立方体在[-1,1]之间。而转换的矩阵是:

在这里插入图片描述
右边的矩阵先与点(表示点的坐标的向量)结合,将物体位移到原点,然后左边的矩阵对其进行缩放。

透视投影(Perspective Projection)

  • 在图形学、艺术以及视觉上最常用的投影。(正交投影并不行,更适用于工程制图)
  • 远处的物体更小,近处的物体更大
  • 平行线不再平行,最后会汇聚到一个单一的点上

在这里插入图片描述

如图所示,平行的铁轨在透视投影的情况下,最终铁规会汇聚到一个点上。

在学习透视投影之前,要先了解一些知识:齐次坐标的属性!
  • (x,y,z,1),(kx,ky,kz,k!=0),(xz,yz,z^2,z!=0),全都代表了同一个(x,y,z)点。齐次坐标(x,y,z,w)所代表的点为(x/w , y/w , z/w)。
  • 比如:(1,0,0,1)和(2,0,0,2) 都代表着(1,0,0)这个点。
那么如何进行透视投影?

下面有两个透视体
在这里插入图片描述

左边为透视投影的透视范围,是一个平截头体,中间的每一条线最后都会汇聚到Camera所在的位置;右边为正交(射)投影的透视范围,因为默认Camera在一个无限远的地方,所以中间的每一条线都是平行的。

要进行透视投影的话,需要完成两步
  • “挤压”这个平截头体,让其成为一个长方体或者立方体,如正交(射)投影那样
  • 然后对这个长方体进行正射投影,就可以得到透视投影的最终效果。
“挤压”的这种变换的实现:

所谓挤压,就是将远平面f按照比例,挤压成近平面n的那种大小,远平面f上的点的坐标就会发生变化:1.中心点不变,比如中心点为(0,0),挤压之后依旧是(0,0),2.其他的点向中心进行偏移,比如近平面是x和y在[-1,1]这个区间上的正方形 ,而远平面f为[-2,2]的正方形,那么远平面挤压过后,也要变为[-1,1]的正方形,那么远平面的点与原来的位置相比,就更靠近中心了。

在这里插入图片描述

如上图所示,要用矩阵来完成这种变换就要找到这个矩阵,找到这个矩阵就意味着找到(x’ , y’ , z’)和(x , y , z)之间的关系,其中(x’ , y’ , z’)在近平面上,(x , y , z)在远平面上。由相似三角形可以得出他们之间的关系:

在这里插入图片描述

在齐次坐标下就可以表示为:

在这里插入图片描述

中间第二个向量表示的是(x’ ,y’ , z’),因为没有找到z和 z’ 之间的关系,所以目前用unkown来表示,然后四个维度都×z,能够得到一种比较简单的表示方法,但是代表的点仍然是原来那个点,z’仍然是unkown,但是发生了变化。

这种将透视投影“挤压”成正交投影的变换,用矩阵表示如下:

在这里插入图片描述

M(persp->ortho)代表着“挤压变换”,(x,y,z,1)代表原始状态下远平面上的点,(nx , ny , unkown , z)代表挤压后远平面的点。

于是,根据上面的这个式子就能够先写出矩阵的一部分信息:

在这里插入图片描述
接下来的任务就是寻找第三行的数值:

第三行的值是有关于z的变换的关系,如果能找到z和 z’ 之间的关系,就能够写出第三行的数值,由观察可以得出:

  • 所有近平面上的点都没有发生变换(因为所有的平面都要挤压的近平面的大小,近平面并不需要挤压,所以不发生变化)
  • 所有远平面上的点的z的分量不会发生变化(因为挤压只挤压了平面的大小,并没有移动远平面的位置)

根据上述第一点,近平面点不变,可以得到:

在这里插入图片描述

因为近平面的点不变,所以输入的点和输出的点应该是相等的,同一个点
在这里插入图片描述

由这个式子可以得出:第三行必定是为(0,0,A , B)的格式,并且

在这里插入图片描述

进一步推到得到:

在这里插入图片描述
然后再利用上述的第二点:在远平面上的任何点的z值都不会发生变换,比如选一远平面上的点为(0,0,f,1),则:

在这里插入图片描述

根据两个等式,就可以求A和B的值:

在这里插入图片描述

最后就能够获得”挤压变换“的矩阵
在这里插入图片描述
接下来应该做什么?

  • 先做正射投影
  • 透视投影的变换就是正射投影和挤压变换的叠加:

在这里插入图片描述

这篇关于GAMES101-现代计算机图形学入门-闫令琪 - lecture4 观测变换(viewing transformation) - 课后笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/237529

相关文章

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

史上最全MybatisPlus从入门到精通

《史上最全MybatisPlus从入门到精通》MyBatis-Plus是MyBatis增强工具,简化开发并提升效率,支持自动映射表名/字段与实体类,提供条件构造器、多种查询方式(等值/范围/模糊/分页... 目录1.简介2.基础篇2.1.通用mapper接口操作2.2.通用service接口操作3.进阶篇3

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Python实现Word转PDF全攻略(从入门到实战)

《Python实现Word转PDF全攻略(从入门到实战)》在数字化办公场景中,Word文档的跨平台兼容性始终是个难题,而PDF格式凭借所见即所得的特性,已成为文档分发和归档的标准格式,下面小编就来和大... 目录一、为什么需要python处理Word转PDF?二、主流转换方案对比三、五套实战方案详解方案1:

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二