光栅化

如何定义视椎体宽高比和垂直可视角度?

fov:垂直可视角度

t:在y轴的高度

n:近平面上的z轴上的点

tan(fov/2)= t/|n|

r:中心点到右边的距离

宽高比(aspect) = 2r/2t = r/t

如何将投射完成的标准立方体显示到屏幕上?

什么是屏幕?

  • 二维数组
  • 每个元素是一个像素
  • 一种经典的光栅成像设备

光栅化:在屏幕上绘画

像素:

  • 在屏幕上最小单位的小方块
  • 由红绿蓝三原色混合而成

屏幕空间

  • 像素都是以(x,y)的形式表示,其中x、y都是整数
  • 像素的范围从(0,0)到(宽度-1,长度-1)
  • 像素的中心在(x+0.5,y+0.5)
  • 屏幕覆盖范围为(0, 0) 到 (宽, 高)

视口变换

  • Z轴被忽略
  • 将原本【-1,1】²的正方体变换为【0,宽】x【0,高】(视口变换)
  • 视口变换矩阵
视口变换矩阵

光栅显示设备

  • 阴极射线管
    • 隔行扫描方法
    • CRT显示器
    • 示波器
  • 帧缓冲器
  • 平板显示设备
    • LCD(液晶显示器)
    • OLED
    • LED(发光二极管)
    • 电子墨水屏

三角形-基本形状单元

  • 最基础的多边形
    • 任何多边形都可以
  • 独特的性质
    • 除非折成两个三角形,否则永远是一个面
    • 三角形的内外很明确
    • 可以利用重心插值进行三角形顶点插值

采样

在某个点对函数求值就是采样,我们通过采样将函数离散化。

采样

Inside函数

inside(tri,x,y)

1:point(x,y)在三角形内

0:其余情况

遍历所有点,判断所有点是否在像素内

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);
    }
}

通过叉乘计算出(见叉乘在图形学的应用)点是否在三角形内

如果碰巧点在三角形的边界,本课程中不做处理,也可以特殊处理

包围盒优化

利用包围盒(Bounding Box)对一定不会包含三角形的像素进行优化

包围盒

对于窄长的三角形并不友好

采样的瑕疵

  • 锯齿
抗锯齿1

通过inside函数渲染出来的三角形有明显锯齿

抗锯齿是图形学中重要的难题

通过对原本三角形做模糊处理再进行采样可以抗锯齿(反走样)

不能先采样再做模糊

之所以会出现锯齿(走样)是因为出现了频谱混叠(后面有讲)

  • 摩尔纹
摩尔纹
  • 车轮效应

信号时间变化太快以至于采样跟不上变化的速度

时域与频域

频域是描述信号在频率方面特性时用到的一种坐标系

时域是描述数学函数或物理信号对时间的关系的一种坐标系。

傅里叶级数展开

傅里叶变换会将时域转化为频域

傅里叶级数展开1 傅里叶级数展开2

将函数表示为正弦余弦的加权和

随着展开式越来越多,越来越接近我们想要表达的函数

采样精度

如果采样的频率不够,还原过来的函数就会越来越不精准

频域和时域可以通过傅里叶变换和逆变换互相转换

傅里叶频域图

傅里叶频域图

滤波

删除特定的频率被称之为滤波

高通滤波:只显示高频信息(只显示边界-锐化),将低频信息盖住

低通滤波:只显示低频滤波(画面变模糊),将高频信息盖住

卷积

滤波=卷积(=平均)

卷积

简化的定义:结果为相邻数的平均值

定理:时域的卷积等于频域的乘积

卷积

频谱混叠

频谱混叠

由于采样稀疏,因此出现频谱混叠从而出现锯齿(走样)如果屏幕中像素非常多,密集的采样就不容易出现走样。

因此使用分辨率高的显示器,频谱的搬移间隔大,不容易出现频谱混叠。

抗锯齿2

同时,将信息进行低通采样再进行采样即可反走样。

反走样(抗锯齿)

解决方法:

  • 通过将每个像素进行模糊卷积f(x,y)
    • 卷积=滤波=平均
  • 然后再对灭个像素的中心取样

在光栅化一个三角形时,像素颜色的平均值f(x,y)= 三角形的覆盖像素的面积

抗锯齿3
超采样抗锯齿(MSAA)

MSAA: Antialiasing By Supersampling

这是一种对反走样的近似

将每个像素的内部多增加采样点再进行模糊卷积

MSAA

MSAA X4

缺点:增加了很多的计算量

其他的抗锯齿方法
  • FXAA (Fast Approximate AA)
    • 快速近似抗锯齿
    • 图像的快速处理
  • TAA (Temporal AA)
    • 对上一帧进行处理

超分辨率

从低分辨率处理成高分辨率

与反走样类似,也是解决了样本不足的问题

目前可使用DLSS(深度学习的方法)进行超分辨率处理

画家算法

灵感来源于画优化

先画(渲染)距离远的,再画(渲染)距离近的。

问题:难以确定谁在前谁在后

画家算法

深度缓冲(Z-Buffer)

  • 深度图-储存每个像素对应的最浅的深度
  • 结果图-储存最终的结果

特别定义:Z越小(越黑)越近,越大越远(与通常的右手系不同,仅仅为了便于理解)

深度缓存1

算法:

//默认深度为无限远
for(each triangle T)
{
    for(each sample(x,y,z) in T)//遍历任意一个三角形中的任意一个像素
    {
        if(z<zbuffer[x,y])//如果此时的深度小于之前记录好的深度
        {
            framebuffer[x,y] = rgb;//三角形着色
            zbuffer[x,y] = z;//更新小的深度
        }
        else
        {
            //...
        }
    }
}

参考资料

GAMES101-现代计算机图形学入门-闫令琪