光栅化(三角形)

透视相机的视椎体

  1. top, bottom,left, right很难去描述一个视椎体
  2. 引入概念:视角fov(field of view),宽高比 aspect ratio(width/height)
  3. 将fov和aspect转换为top, bottom, left, right: tan(fovY/2) = top / |near|, aspect = right / top

什么是屏幕?

  1. 像素的数组
  2. 数组的大小=分辨率
  3. 典型的光栅成像设备

像素

  1. pixel: picture element缩写
  2. 像素是带颜色的小方块,是最小单位
  3. 颜色是红绿蓝的混合

定义屏幕空间

  1. 像素点坐标是从(0, 0)到(width -1, height - 1)的范围,且都是整数
  2. 像素点(x, y)中心点位于(x + 0.5, y + 0.5)
  3. 现在要将标准立方体[-1,1] * [-1, 1]转换成(0, width) * (0, height),分两步,先缩放到[-width/2, width/2],再做平移,等同于左乘矩阵,(width/2, 0, 0, width/2, 0, height/2, 0, height/2, 0, 0, 1, 0, 0, 0, 0, 1)

为什么选择三角形

  1. 最基础的多边形
  2. 其他多边形都拆解成三角形
  3. 能确定唯一的平面
  4. 内和外定义明确
  5. 三角形内任意一点,与三个顶点之间的关系,可以构成一个线性变化,即插值

如何进行光栅化?

  1. 采样: 给定一个函数,是连续的,给函数一个input,求output,给函数离散化
    1. 一般用像素中心进行采样
    2. 给定一个三角形tri,和坐标x,y,以及函数inside(tri, x, y),如果函数返回1,表示点在三角形内,反之则在三角形外
    3. 将屏幕上的所有像素中心的坐标一一代入,求解就是光栅化
    4. 优化方案: 无需计算所有像素点,只需要计算包含三角形的最小矩形范围的像素点即可,即包围盒
    5. 更优化方案: 每一行单独计算包围盒,但实际操作起来比较复杂
    6. 锯齿问题: 采样率过低

抗锯齿(反走样)

  1. 采样带来的失真
    1. 锯齿: 判断点是否在三角形内
    2. 摩尔纹: 图片采样中,去除了偶数行的像素
    3. 车轮效应: 人眼在时间中的采样跟不上车轮的转速
  2. 先对三角形进行模糊,再采样
  3. 频域
    1. 频谱图: 中间亮的部分为低频,外部黑的部分为高频
    2. 高通滤波: 仅保留图片的高频部分,抹除低频部分,得到的效果是图片中边界越来越明显,而非边界部分则一片黑
    3. 低通滤波: 仅保留图片的低频部分,抹除高频部分,得到的效果是图片模糊,边界不清
    4. 数字图像处理
    5. 滤波: 去掉一个频域的信息,=平均=卷积
  4. 卷积: 任意一个信号与其周围做的一次加权平均
  5. 卷积定理:时域的乘积 = 频域的卷积
  6. 抗锯齿的基本方法
    1. 加大分辨率: 成本过高,不现实
    2. MSAA: 将每个像素点进行一次拆解,拆成4x4,然后在判断每个点是否在三角形内,最后根据在三角形内点的个数做一次加权平均,得到颜色的百分比,本质是先模糊,在采样
    3. FXAA: 快速近似抗锯齿,属于后期处理,根据生成的图像,先找到图像中的边界,再换成没有锯齿的边界
    4. TAA: 将MSAA对应的样本应用在时间上,沿用上一帧的点的MSAA的结果,在静态画面中比较实用
    5. 超分辨率:从低分辨率到高分辨率,采样不足,使用深度学习的算法来猜测补全缺失点

深度缓存

  1. 解决可见性,遮挡问题
  2. 画家算法:先绘制远处的,在绘制近处的,无法解决深度问题,如果出现互相遮挡情况,复杂度O(nlog(n))
  3. z-buffer
    1. 针对每一个像素,记录离我们最近的一个距离
    2. 绘制图形的时候,除了frame-buffer存储颜色信息外,还有一个z-buffer存储深度信息
    3. 如果按相机放在原点,朝向-z方向,那z永远都是负的,z越大离我们越近,越小离我们越远,为了方便理解,我们将z的定义改为到原点的距离,z越小离我们越近,越大离我们越远
    4. 深度缓存算法: 遍历三角形的每个点,如果z小于深度缓存的值,则绘制,且更新深度缓存值,否则不绘制
    5. 深度缓存算法复杂度O(n)
    6. 深度缓存算法基于一个前提,同一个采样点深度,不会出现同样的z值,因为z是浮点数,要对浮点数做相等判断很难(强行解释)
    7. 深度缓存算法广泛应用在所有硬件上