将每个像素点划分为更细的子采样点,根据子采样点的覆盖率最终计算出像素的颜色
SSAA:首先判断子采样点是否在三角形内部,同时对每个子采样点维护一个深度值和颜色值(深度值初始化为无穷大,颜色值初始化为{0,0,0}),对每个像素通过覆盖测试和遮挡测试的每个子采样点都要经过一次着色计算,并且存入颜色缓冲区,得到了每个采样点的颜色之后,我们将每个像素点内部所细分的采样点的颜色值全部加起来再求均值,作为该像素点的抗走样之后的颜色
伪代码如下:
for(x in bounding box)
{
for(y in bounding box)
{
for (int j = 0; j < n; j++)
{
index=getindex(x,y)+j;(子采样点索引值扩大四倍)
if(子采样点在三角形内部)
{插值得到当前子采样点深度值zp;}
if(zp<深度缓冲区的深度值)
{
插值得到每个子采样点所需的属性;
对每个子采样点做一次着色运算
更新子采样点深度缓冲区的深度值;
将子采样点的颜色存入颜色缓冲区;
}
}
像素点颜色+=所有子采样点颜色/n
}
}
}
MSAA:
MSAA的真正工作方式是,每个像素只运行一次片段着色器,无论多少子样本被三角形所覆盖。片段着色器运行着插值到像素中心的顶点数据,最后颜色被储存近每个被覆盖的子样本中,每个像素的所有颜色接着将平均化,每个像素最终有了一个唯一颜色。在前面的图片中4个样本中只有2个被覆盖,像素的颜色将以三角形的颜色进行平均化,颜色同时也被储存到其他2个采样点,最后生成的是一种浅蓝色。
注意:MSAA在实际操作的时候,同样会维护所有子采样点的color buffer和depth buffer,每次对pixel中心计算shading的时候(对pixel中心计算shading的时候一样要判断子采样点是否在三角形内部,维护中心深度值),会根据depth值(因为可能不止一个三角形拥有这个像素)和三角形覆盖关系判断是否把颜色值写入。
伪代码如下:
for(x in bounding box)
{
for(y in bounding box)
{
for (int j = 0; j < n; j++)
{
index=getindex(x,y)+j;(子采样点索引值扩大四倍)
if(子采样点在三角形内部)
{
插值得到当前像素中心深度值z_interpolated;
{
if(z_interpolated<深度缓冲区像素中心点的深度值)
{更新深度缓冲区的深度值;
计算像素中心颜色;
将像素中心颜色存入颜色缓冲区
}
}
}
for (int j = 0; j < n; j++)
{
index=getindex(x,y)+j;(子采样点索引值扩大四倍)
插值得到当前子采样点深度值zp;
if(子采样点在三角形内部)
{
if(zp<深度缓冲区的深度值)
{
更新深度缓冲区的深度值;
复制像素中心颜色到子采样点颜色缓冲区;
}
}
像素点最终颜色+=所有子采样点颜色/n
}
}
}
参考链接:
https://blog.csdn.net/qq_38065509/article/details/105598277
https://www.shangmayuan.com/a/0ac3c44174ee4ee8a5cfccad.html
https://www.zhihu.com/question/20236638/answer/44821615