GAMES101-现代计算机图形学学习笔记(05)

GAMES101-现代计算机图形学学习笔记(05)

原课程视频链接以及官网
b站视频链接: link.
课程官网链接: link.

视图/摄像机变换

确定投影范围

上一节说了投影实质上是通过一个长方体(正交投影)或者视锥(透视投影)限定一个范围,然后把范围内的坐标投影在二维空间上,所以这里涉及到了如何为不同的投影方式确定范围。

正交投影

正交投影比较好理解,即如何定义一个长方体,我们只需要知道高,宽和深坐标。所以需要的参数是height_start,height_end, width_start,width_end, znear(近平面), zfar(远平面)六个参数
在这里插入图片描述

透视投影

透视投影需要定义的范围是一个视锥,而一旦确定了视锥就可以通过上文的l逻辑来构造透视投影矩阵,范围如图所示:在这里插入图片描述
我们这里从二维平面来讨论构建透视矩阵需要哪些参数,先把视锥往zoy平面压平,然后只取视锥的上半部分,结果如下图所示:
在这里插入图片描述

fovY表示视野角度,同时已知近平面深度为n,远平面深度为f,宽高比为aspect,所以可以通过相似三角形和角度关系求得:
tan f o v Y 2 = t n \tan \frac{f o v Y}{2}=\frac{t}{|n|}
aspect = r t r = a s p e c t t \text {aspect}=\frac{r}{t} → r= {aspect} \cdot {t}
即构建透视矩阵需要视野角度fov,宽高比,znear, zfar四个参数。

视口变换

在M(model)V(view)P(projection)变换之后,我们已经得到了三维坐标在二维屏幕上的投影,同时也得到了投影区域(Canonical Cube)。之后所需要的就是视口变换。视口变换是把三维坐标与屏幕上指定的区域进行映射,简单来说就是我们在屏幕上规定了一块区域,然后将我们投影的坐标规定好,只能画在这块区域中,这就是视口变换所做的事情。

屏幕空间

既然要找到这个映射关系,那么屏幕自身也应该有自己的坐标系,也就是屏幕空间。我们可以把屏幕上的像素看成是像素的矩阵形式,它的x,y坐标都是从0,0开始的,里面每一个坐标都可以看做包含了一个像素。
在这里插入图片描述

屏幕空间的标准化

这一步需要把Canonical Cube [ 1 , 1 ] 2 ∈[-1,1]^{2} 变换到 [ 0 ,  width  ] × [ 0 ,  height  ] [0, \text { width }] \times[0, \text { height }] ,width和height就是视口变换所需要规定的区域的长和宽。
在这里插入图片描述
这一步变换可以看成是二维平面上矩阵的平移和缩放,故有以下变换公式:
M viewport = ( width 2 0 0 width 2 0 height 2 0 height 2 0 0 1 0 0 0 0 1 ) M_{\text {viewport}}=\left(\begin{array}{cccc} \frac{\text {width}}{2} & 0 & 0 & \frac{\text {width}}{2} \\ 0 & \frac{\text {height}}{2} & 0 & \frac{\text {height}}{2} \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right)

光栅化

在视口变换之后,我们已经在屏幕上规定了一块区域用于映射对应的坐标,所以后面就需要通过光栅化来把三维图元映射成二维像素。光栅化也分为光栅化线和三角形,下面主要讲光栅化三角形

为什么选取三角形

①基础图元:三角形可以看成是基础图元,用它可以构建出不同的图元
②平面:一个三角形必定是一个平面
③内外定义:三角形是可以通过顶点环绕顺序来描述其内外性的,方便做面剔除等操作
④插值:三角形内部插值十分方便

如何确定三角形在屏幕上的像素

当输入三角形顶点坐标时,如何判断对应屏幕上的像素区域?答案是采样

采样

采样就是对方程离散化的一个过程,在这里我们通过对每一个像素进行判断,如果它的中心点在三角形内部,那么它就是属于三角形的,我们应该在屏幕上将其画出来,而判断方法之前也说过,可以通过叉乘来实现
在这里插入图片描述
所以当给定一个三角形时,我们只需要确定其包围盒范围 [ x m i n , x m a x ] [xmin,xmax] [ y m i n , y m a x ] [ymin,ymax] ,那么对应的伪代码就可以写出来:

 for (int x = 0; x < xmax; ++x)   
	 for (int y = 0; y < ymax; ++y)     
	 	image[x][y] = inside(tri,x + 0.5,y + 0.5);  // 判断点是否在三角形内部

当然还有其他更快的画三角形方式:
在这里插入图片描述

原创文章 9 获赞 3 访问量 508

猜你喜欢

转载自blog.csdn.net/qq_36242312/article/details/105695242