Rasterization

  1. Rasterization
    1. 直线光栅化
    2. 三角形光栅化 Sampling 采样
      1. Antialiasing 反走样
        1. 原理:
        2. 解决方法
    3. Visibility/occlusion

Rasterization

fov

视锥由fovY和aspect即可定义
aspect ration = width/height
What is a screen?

  • An array of pixels(1920*1080)
  • Size of the array: resolution
  • A typical kind of raster display

Raster == screen in German

  • Rasterize == drawing onto the screen

Pixel (FYI, short for “picture element”)像素

  • For now: A pixel is a little square with uniform color
  • Color is a mixture of (red, green, blue)
  • (x+0.5,y+0.5)为(x,y)像素的中心 像素从(0,0)到(width - 1,height - 1)

所有变换之后 现在图片上仍是一堆多边形 下一步多边形打散成像素—光栅化 Drawing to Raster Displays

直线光栅化

  • DDA数值微分算法
    1.当|k|<1时,从起点开始画起每次x = x+1, y="y+k," 并将y四舍五入,得到新的x,y就是像素点应该画的地方 2.当|k|>1时,从起点开始画起每次y = y+1, x = x+1/k, 并将x四舍五入,得到新的x,y就是像素点应该画的地方
  • 中点Bresenham算法
    f(x,y)=y-kx-b 考虑0 0的时候中点在直线上方 选择右边,当f(x+1,y+0.5) < 0的时候中点在直线下方 选择右上
    1
    2
    3
    4
    5
    y=y0
    for x=x0 to x1 do
    draw(x,y)
    if f(x+1,y+0.5)<0 then
    y = y+1
    由于f(x,y)=(y0-y1)x+(x1-x0)y+x0y1-x1y0
    利用增量算法 f(x+1,y) = f(x,y)+y0-y1 f(x+1,y+1)=f(x,y)+y0-y1+x1-x0
    代码简化得
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    y=y0
    d=f(x0+1,y0+0.5) - f(x0, y0)=y0-y1+0.5(x1-x0)
    for x=x0 to x1 do
    draw(x,y)
    if d<0 then
    y = y+1
    d = d+x1-x0+y0-y1
    else
    d = d+y0-y1
    //为方便计算可将d相关都乘2 d=2(y0-y1)+x1-x0 d+=2(y0-y1) .. 由于只需判断d的正负所以乘二不影响结果
    实现时根据k的大小分情况 k绝对值>1时x和y互换

三角形光栅化 Sampling 采样

把蕴含几何信息的数据转化为屏幕上的像素 一条直线该用哪些像素点去逼近,一个三角形用哪些像素集合表示

三角形优势: 最基础多边形 一定在一个平面 内外定义清晰 定义三个顶点属性可以在内部渐变(重心坐标插值)

关键: 确定像素中心点和三角形的关系

将函数离散化discretize a function by sampling = Sample 2D Positions
Sampling is a core idea in graphics
对像素点中心采样

1
2
3
4
5
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);

inside具体实现:
判断点是否在三角形内 三边分别叉乘 想要光栅化的三角形的三个顶点P0,P1,P2,以及检测点Q 分别计算P0P1×P0Q,P1P2×P1Q,P2P0×P2Q,三者同号则代表Q处于三角形内部,不同号则在三角形外部

效率提升:
包围盒Bounding Box AABB 包围住想要测试的三角形 减少对不包含三角形的像素的检测
Incremental Triangle Traversal 直接找三角形边界(相当于对每行的包围盒)

Antialiasing 反走样

抗锯齿
采样产生的问题Sampling Artifacts:

  • Jaggies 锯齿(空间采样上的错误)
  • Moire 摩尔纹(如,采样时跳过奇数行奇数列)
  • Wagon wheel effect 马车轮效应:人眼在时间上的采样跟不上运动速度
  • 采样伪影的原因:信号频率太快,采样速度跟不上

原因:信号变化太快导致采样跟不上

Blurring (Pre-Filtering) Before Sampling 先模糊(滤波)再采样
Blurred Aliasing先采样再模糊(不行

原理:

Frequency Domain频域

傅里叶变换把函数分成很多正弦余弦函数的和 分解成不同频率的段

Higher Frequencies Need Faster Sampling

对高频的采样出的结果不能恢复原来的函数 不准确

采样与函数频率相关

以同一个采样频率对不同频率信号获取了同样的信息,称之为走样

Filtering = Getting rid of certain frequency contents 滤波 去掉某个频率的信息

傅里叶变换FT把时域变到频域

filter
低频信号靠近中心 且低频信号多故亮

图像的边界处变化非常大 -> 高频信息

High-pass filter高通滤波 只剩高频 故只剩边界

Filtering = Convolution卷积(= Averaging) 滤波=平均=卷积
convolution

卷积图形学上简单理解:对信号及周边求平均

时域上的卷积=频域上的乘积
Convolution Theorem

先傅里叶变换为频域乘再逆傅里叶变换回去 低通滤波

Box Filter 低通滤波器 1/9是为了像素大小不变
box越大频域越小

Sampling = Repeating Frequency Contents
Repeating Frequency Contents

采样即为时域上函数乘一系列的冲激函数得到一系列的点
在频域上即FT之后的函数和一系列冲击函数FT之后仍为冲激函数的卷积 得到一系列FT之后函数的复制
所以采样就是重复一个原始信号的频谱

走样就是频谱在复制的过程中发生了混合
Mixed Frequency Contents

采样率变低,采样间隔变大,波长变大,频率变小
采样频率小 复制间隔就小 (时域和频域不一样)

解决方法

Reduce Aliasing Error

  • Increase sampling rate 增加采样频率 相当于在频谱上增大复制的间隔
  • Antialiasing 反走样 先模糊(低通滤波)再采样

    Antialiasing

    去掉高频的信号来防止重叠

    变模糊的方法—用一定的滤波器去卷积(求块的平均)(可以是时域上的一个像素点)
    对每个三角形覆盖的像素都求像素内的覆盖区域的平均

  • SSAA
    增加采样点 对每一个像素点分成更小的”像素点”再求平均
    最终得到每个像素点的覆盖率 故可认为合并了采样操作
    并不是提高采样率
  • MSAA
    优化SSAA看有多少个子采样点在三角形中对母采样点的数据乘百分比
    不必每个采样点都进行着色计算 只计算像素中心的 然后分开计算子采样点在三角形中个数得到百分比 再用像素中心的乘百分比即可
    在光栅化阶段,判断一个三角形是否被像素覆盖的时候会计算多个覆盖样本(Coverage sample),但是在pixel shader着色阶段计算像素颜色的时候每个像素还是只计算一次
    和deferred shading 不兼容 场景都先被光栅化到GBuffer上去了,不直接做shading

  • 其它抗锯齿方法:

    • FXAA 图像处理上找到有锯齿的再换成无锯齿的
    • TAA 复用上一帧的像素点

      超分辨率 拉大图
      DLSS深度学习方法

Visibility/occlusion

Painter’s Algorithm - Paint from back to front, overwrite in the framebuffer 新画的覆盖之前画的
深度不好判断 绘制顺序不同可能结果不同

  • Z-Buffer 深度缓存

同步生成两张图

  • frame buffer stores color values
  • depth buffer (z-buffer) stores depth Store current min. z-value for each sample (pixel) 之前mvp变换得到的z值 近处值小所以黑(距离为正)
1
2
3
4
5
6
7
8
9
//Initialize depth buffer to ∞
//每一个像素内记录最小深度
for (each triangle T)
for (each sample (x,y,z) in T)
if (z < zbuffer[x,y]) // closest sample so far
framebuffer[x,y] = rgb; // update color
zbuffer[x,y] = z; // update depth
else
; // do nothing, this sample is occluded

和顺序无关 O(n)的复杂度 本质是求最小值不是排序 和绘制顺序无关 可以对每个采样点zbuffer 处理不了透明物体

×

喜欢就点赞,疼爱就打赏