上一节我们了解了图形的各种变换,缩放,平移,以及两种投影:
正交投影,透视投影
经过这些变换(我们叫做MVP操作 , 分别是模型变换, 视图变换 , 投影变换),我们成功的将空间里面的物体变换缩放投影至了[-1 , 1]
的三次方的区域了,那么接下来我们要做什么呢?
就是将物体画在屏幕上,也就是光栅化(Rasterization)
1.透视区域的定义
之前的透视变换里面我们是将一个锥形的区域先压缩再做了正交投影,而且这个区域我们定义几个量: f , n , b , t , r , l 来框定这个区域的大小,其中我们加几个新的量:
宽高比:相机的视图的区域的长宽比
垂直可视角度:基于垂直面而且位于视线边缘的两个线的夹角
视角越大,就是广角,拉伸明显,视角小就是长焦
我们发现,只要定义了长宽比和可视角度以及n平面的位置,就可以直接计算出这个可视椎体的其他边界的位置了
2.成像
有了区域,就要将他显示在屏幕上了
2.1屏幕
什么是屏幕?
1.一个二维的数组
2.每一个数组的元素是一个像素
3.数组的大小就是屏幕的尺寸
比如 LCD-液晶显示器是一种屏幕,使用液晶的偏转控制光的偏射,从而控制光能量的变化:
比如左下的图,竖直的光在经过液晶的偏转后,可以从水平的偏振板里射出
屏幕定义:
1.屏幕是有一个个小方块像素构成,左下角的像素坐标是(0 , 0),每一个像素的下标表示的是它的左下角
2.像素下标范围是(0 , 0 ) ~ (width - 1 , height - 1)
3.像素的中心是(x + 0.5 , y + 0.5)
4.所有像素组成的屏幕范围就是(0 , 0 ) ~ (width , height )
2.2光栅化
光栅(raster)就是屏幕的意思,而光栅化(Rasterize) 就是成像的过程 ,呈现的最小单位是像素(Pixel),光栅化的过程:
第一步,将区域适应屏幕
对于我们之前投影变换得到的[-1 , 1]
的三次方的可视,我们先不考虑它的z轴,先把x y 缩放至屏幕的位置和大小,只需要对可视范围进行时口变换,变换需要乘的矩阵:
(平移是为了把区域移至xy的第一象限)
第二步,采样
将区域适应屏幕后,我们就可以拿到图像里面所有面点的信息来呈现在屏幕像素上,假如我们有一个三角区域需要配绘制,就是对屏幕的输入是三角形三个点坐标和颜色,我们如何绘制像素呢?
不难看出,我们这最重要的是要判断每一个像素点(特别是三边上的像素)与这个三角形区域的位置关系,这样我们好判断这个像素要绘制成什么颜色
我们设定一个函数insert( t , x , y) ,判断三角形 t 里面是否有像素(x , y ),返回的是true和false,是用点与向量的叉乘判断位置(因为叉乘的结果正负就可以判断方位),将结果存在is_in[x][y]里面,之后我们就可以使用这个来继续个给像素上色
for( int x = 0 ; x < maxx ; x++)
for ( int y = 0 ; y < maxy ; y ++)
is_in[x][y] = inside( t , x + 0.5, y + 0.5)
但是我们不用每画可以区域看遍历所有像素,只需要在三角形的包围盒里就行
for( int x = 0 ; x < t.max_x ; x++)
for ( int y = 0 ; y < t.max_y ; y ++)
is_in[x][y] = inside( t , x + 0.5, y + 0.5)
根据is_in[x][y]填上色后就得到了一个锯齿的三角形,锯齿原因是采样率太小,出现走样的问题
3.走样(锯齿)
那如何抗锯齿呢?也就是如何反走样呢?让我们的图像更真实呢?
3.1 Pre_Filter滤波处理
我们可以先对图片进行模糊的处理,准确说是滤波处理Pre_Filter,再对每一个点进行采样
滤波处理就是去掉一些频率,再进行采样
3.2 什么是滤波
对图片的滤波处理一般有低频滤波(Low_Pass Filter)和高频滤波(Hight_Pass Filter)其实就是去掉图片的高频或者低频区域
什么是图片的高频低频?
像素快速变化的区域就是高频区域,像素没什么变化的区域就是低频区域
不难理解:这样高频的区域其实就是我们图片的边界或者是线条,那我们模糊图片其实就是去掉图片的高频区域,这样去掉边界我们就看不清边界,也就是说模糊了图片
如何得到图片的高低频?
我们使用傅里叶变换将信息提取成频率的形式(提取过程不用知道),如下图,中间是低频,四周是高频,白色表示这个频率的区域的大小
当我们去掉高频区域,也就是只保留中间一个圆形区域的频率后,就模糊了图片
所以,这种去掉某一个频率,模糊图片的过程就是一种滤波
3.3 怎么实现滤波
1.对于一张图片的像素而言,就是对每一个像素,和他四周3*3的区域的像素取一个平均,就是将实物卷积,将这个平均值填回原来像素的位置,这样就模糊处理
2.对于频率而言,先得到图片的傅里叶变换频铺, 将他与我们3*3的区域对应的频铺相乘,就是对频率进行乘积,得到的频谱再做一遍逆傅里叶变换,就得到我们模糊的图片
其中中间的这个3*3的区域对应的频铺就是我们的低频滤波器,因为只保留了低频的区域,
就这样我们成功的将图片(模糊处理)低频滤波处理了,再进行采样就可以反走样(抗锯齿)了
步骤:对于每一个像素,将他周围3*3区域像素取平均,得到灰度值(就是这个像素的亮度)最后重新采样,最后显示时,对应颜色会有亮度大小
4. 反走样的具体实现
我们回到绘制三角形,对于每一个像素,我们将他划分为更多的小的区域,然后判断这个大像素里面有多少小的像素在三角形内部,求出这个占比,这个占比其实就是我们的灰度值。
对于每一个像素我们划分区域
计算三角形在每一个像素内部的占比
在根据这个灰度值进行采样最后显示不同亮度的颜色
这个过程的反走样叫做MSAA,除了这个还有FXAA,TAA
以上就是games101的光栅化的全部知识了,作者记录学习所用