Rasterization
视锥由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就是像素点应该画的地方 1时,从起点开始画起每次x> - 中点Bresenham算法
f(x,y)=y-kx-b 考虑00的时候中点在直线上方 选择右边,当f(x+1,y+0.5) < 0的时候中点在直线下方 选择右上 由于f(x,y)=(y0-y1)x+(x1-x0)y+x0y1-x1y01
2
3
4
5y=y0
for x=x0 to x1 do
draw(x,y)
if f(x+1,y+0.5)<0 then
y = y+1
利用增量算法 f(x+1,y) = f(x,y)+y0-y1 f(x+1,y+1)=f(x,y)+y0-y1+x1-x0
代码简化得实现时根据k的大小分情况 k绝对值>1时x和y互换1
2
3
4
5
6
7
8
9
10y=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的正负所以乘二不影响结果
三角形光栅化 Sampling 采样
把蕴含几何信息的数据转化为屏幕上的像素 一条直线该用哪些像素点去逼近,一个三角形用哪些像素集合表示
三角形优势: 最基础多边形 一定在一个平面 内外定义清晰 定义三个顶点属性可以在内部渐变(重心坐标插值)
关键: 确定像素中心点和三角形的关系
将函数离散化discretize a function by sampling = Sample 2D Positions
Sampling is a core idea in graphics
对像素点中心采样
1 | for (int x = 0; x < xmax; ++x) |
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频域
傅里叶变换把函数分成很多正弦余弦函数的和 分解成不同频率的段
对高频的采样出的结果不能恢复原来的函数 不准确
采样与函数频率相关
以同一个采样频率对不同频率信号获取了同样的信息,称之为走样
Filtering = Getting rid of certain frequency contents 滤波 去掉某个频率的信息
傅里叶变换FT把时域变到频域
低频信号靠近中心 且低频信号多故亮
图像的边界处变化非常大 -> 高频信息
High-pass filter高通滤波 只剩高频 故只剩边界
Filtering = Convolution卷积(= Averaging) 滤波=平均=卷积
卷积图形学上简单理解:对信号及周边求平均
时域上的卷积=频域上的乘积
先傅里叶变换为频域乘再逆傅里叶变换回去 低通滤波
Box Filter 低通滤波器 1/9是为了像素大小不变
box越大频域越小
Sampling = Repeating Frequency Contents
采样即为时域上函数乘一系列的冲激函数得到一系列的点
在频域上即FT之后的函数和一系列冲击函数FT之后仍为冲激函数的卷积 得到一系列FT之后函数的复制
所以采样就是重复一个原始信号的频谱
走样就是频谱在复制的过程中发生了混合
采样率变低,采样间隔变大,波长变大,频率变小
采样频率小 复制间隔就小 (时域和频域不一样)
解决方法
Reduce Aliasing Error
- Increase sampling rate 增加采样频率 相当于在频谱上增大复制的间隔
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 | //Initialize depth buffer to ∞ |
和顺序无关 O(n)的复杂度 本质是求最小值不是排序 和绘制顺序无关 可以对每个采样点zbuffer 处理不了透明物体