光栅化
三角形的光栅化
屏幕的表示
一个二维的像素数组,如1920×10801920\times10801920×1080数组的大小一个典型的光栅成像设备光栅化(Rasterize):把物体画在屏幕上的过程
像素:表示一个固定颜色的方块,一个像素内的颜色可以用rgb表示
屏幕坐标系的定义:
例如:蓝色像素的坐标为(2,1),该像素的中心为(2.5,1.5)
屏幕覆盖范围为(0,0)到(width,height)
下面我们将标准立方体[−1,1]3[-1,1]^3[−1,1]3映射到该屏幕范围内
先忽略z
将x,y从[−1,1]2[-1,1]^2[−1,1]2映射到[0,width]×[0,height][0,width]\times[0,height][0,width]×[0,height]
视口变换矩阵如下:
Mviewport=(width200width20height20height200100001)M_{viewport}=\begin{pmatrix} \frac{width}{2} & 0 & 0 & \frac{width}{2}\\ 0 & \frac{height}{2} & 0 & \frac{height}{2}\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{pmatrix} Mviewport=⎝⎜⎜⎛2width00002height0000102width2height01⎠⎟⎟⎞
三角形
所有多边形的基础内部一定是平面三角形内外好界定(向量叉积)通过三角形三个顶点以及内部点的关系可以渐变内部点的属性判断像素和三角形的位置关系
通过采样的方法进行判断
用inside(tri,x,y)inside(tri,x,y)inside(tri,x,y)函数判断点是否在三角形内
采样,光栅化
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);
如何判断点Q是否在三角形P1P2P3P_1P_2P_3P1P2P3内?
P1P2×P1Q,P2P3×P2Q,P3P1×P3QP_1P_2\times P_1Q,P_2P_3\times P_2Q,P_3P_1\times P_3QP1P2×P1Q,P2P3×P2Q,P3P1×P3Q全为正或者全为负则说明Q在三角形内,否则在三角形外,若在三角形边界上可自己定义(OpenGL内:上边和左边为三角形内,左边和下边为三角形外)
反走样
采样理论
采样出现的问题
出现锯齿(Jaggies),空间采样
出现摩尔纹(Moire),空间采样
车轮效应(Wagon wheel dffect),时间采样
例如:风扇旋转有时旋转方向逆转了
走样的本质:采样速度跟不上信号变换速度
反走样的做法:
增加分辨率
模糊(低通滤波)→采样
MSAA(增加采样点,计算覆盖率)
FXAA(Fast Approximate AA,快速近似,先出有锯齿的图,再换边界)
TAA(Temporal AA,复用上一帧的每个像素值)
超分辨率问题
低分辨率图像拉大后出现走样问题
细节缺失→DLSS(Deep Learning Super Sampling),通过深度学习的方法猜测
可见性与遮挡
画家算法(painter algorithm) 对每个图形的深度排序(O(nlogn))先画远处的图形,后画近处的图形存在互相遮挡的现象 深度缓存算法(Z-buffering) 对每个像素(或采样点)最浅深度排序(其实是记录最小值,O(n))生成frame buffer和depth buffer(z-buffer)默认深度z恒为正与绘制顺序无关深度缓存算法
for(each triangle T)for(each sample(x,y,z) in T)if(z<zbuffer[x,y])//closest sample so farframebuffer[x,y]=rgb; //update colorzbuffer[x,y]=z; //update depthelse;//do nothing,this sample is occluded