AntiAliasing学习笔记

简介

MSAA是直接硬件支持的,使用pattern在一个像素上做多次fragment计算,最后对去结果做平均的方式,这是在输出之前对结果做滤波,但是这个方法的缺点是占用的显存会变成原来的pattern采样点的倍数。当然这个MSAA多重采样的性质也可以用到别的需要这个这特特性的地方,比如Voxel化

FXAA和SMAA都是形态学方法抗锯齿,简单而言就是找到边界,在边界位置做低通滤波,即采样求平均值,就可以做到抗锯齿

TAA则是采用Temporal的方法,做时间上的滤波,需要注意上一帧的数据在当前帧是否被遮挡住了

FXAA

FXAA的核心思路就是查找当前边界并做滤波,通常称为形态学方法,实现参考FXAA3.11

  1. 边缘检测用灰度值,或者要效率高点直接使用Green通道也行,虽然效果会差一点(其实可以看颜色频谱分布,绿色在中间,而且所占的频谱范围更广)

  2. Local Contrast Check: 采样上下左右的点的灰度值,计算出最大contrast,如果对比度不大,就可以直接判断当前像素点不在边缘上

    AntiAliasing学习笔记_第1张图片

    l.contrast < max(_ContrastThreshold, _RelativeThreshold * l.highest); 
    
  3. Sub-pixel Aliasing Test: 对当前像素周围所有像素,计算当前的Sub-pixel混合权重,让blend更平滑一点

    AntiAliasing学习笔记_第2张图片

     float DeterminePixelBlendFactor (LuminanceData l) {
           
         float filter = 2 * (l.n + l.e + l.s + l.w);
         filter += l.ne + l.nw + l.se + l.sw;
         filter *= 1.0 / 12;
         filter = abs(filter - l.m);
         filter = saturate(filter / l.contrast);
    
         float blendFactor = smoothstep(0, 1, filter);
         return blendFactor * blendFactor * _SubpixelBlending;
     }
    
  4. 边缘检测

    1. Vertical/Horizontal Edge Test:用类似于Sobel算子的核计算水平和竖直方向的梯度,梯度更大的方向作为边缘的方向
    2. End-of-edge Search:因为边缘有可能是曲线,所以我们需要找到真正需要Blend的侧面,而且求出blend的权重,需要把uv朝着真正的边界偏移半个像素,并朝着两边分别查找边 End-of-edge ,最后权重为 0.5 - shortestDistance / (pDistance + nDistance)
      AntiAliasing学习笔记_第3张图片
  5. 比较 Sub-pixel Aliasing Test 计算出的Blend系数与边缘检测得到的Blend系数,选择更大的那个作为混合的权重

     float pixelBlend = DeterminePixelBlendFactor(l);
     EdgeData e = DetermineEdge(l);
     float edgeBlend = DetermineEdgeBlendFactor(l, e, uv);
     float finalBlend = max(pixelBlend, edgeBlend);
    

AntiAliasing学习笔记_第4张图片AntiAliasing学习笔记_第5张图片

SMAA

SMAA在paper给的代码里面已经实现的很好了,所以unity也基本是拿了原来paper的代码直接用的

SMAA流程

TAA

TAA主要包含:

  1. MotionVector 计算
  2. Temporal Reprojection 对输出纹理滤波

TAA流程

  • jittering view frustum
    • 16 first samples of halton(2,3)
  • generating velocity buffer
    • camera motion + dynamics (manual tagging, eurgh)
  • reprojection using velocity
    • based on closest (depth) fragment
  • neighbourhood clipping
    • center clip to RGB min max of “rounded” 3x3 region
  • motion blur fallback
    • kicks in when || v || > 2, and full effect at 15
    • does not apply to history

参考PlayerDead的Inside实现的TAA,效果对比如下图
AntiAliasing学习笔记_第6张图片AntiAliasing学习笔记_第7张图片在Unity上的实现代码 https://gitee.com/alienity/SRPTAA2,有兴趣的同学可以下载下来学习参考

引用

[1] https://catlikecoding.com/unity/tutorials/advanced-rendering/fxaa/

[2] https://developer.download.nvidia.cn/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf

[3] https://docs.nvidia.com/gameworks/content/gameworkslibrary/graphicssamples/d3d_samples/fxaa311sample.htm

[4] https://github.com/playdeadgames/temporal

你可能感兴趣的:(图形基础巩固)