1. History Color失效的情况
当物体运动或者相机运动时,我们需要通过reprojection操作来获得某个pixel在前一帧中的屏幕空间位置,然后从该位置获取history color。然而,并不是在任何情况下,history color都是正确的。
1.1. 相机/物体运动导致的history color失效
如 图 1 所示,当相机在场景中运动时,当前帧中,某个pixel对应的场景采样点为红色点,为了得到该采样点的history color,我们使用上一帧的MVP矩阵来将 该红色采样点投影到屏幕空间中后,然而,history buffer中该屏幕空间位置中存储的history color为绿色采样点的history color,然而我们需要的是红色采样点的history color,从而导致我们获得了一个invalid的history color。

上述情况产生的根本原因在于某些fragment在当前帧可见,然而在上一帧不可见。导致该情况的原因可能是相机的运动或者物体的运动。例如,当相机运动速度较快时,屏幕边缘处的fragment就会在上一帧中不可见,从而导致history buffer中没有存储这些fragment的history color。
1.2. Shading导致的history color失效
当物体或者相机运动时,可能会导致当前帧中的某个fragment的history color没有被存储在history buffer中,从而导致获得的history color是无效的。
然而,即使我们能够在history buffer中获取到某个fragment对应的history color,该history color依然可能无效。假设在上一帧中某个fragment被一个红色的光源照亮,然而在当前帧中该光源颜色变为绿色,从而会导致该fragment的颜色由于shading的变化而不同。最终导致,上一帧的history color不可用,即history color无效。
导致shading的变化原因有很多,例如:
- 光照环境的改变(光源颜色变化、光源开关等)
- 阴影的变化(是否处于阴影中)
- 半透明物体的影响
任何会对导致pixel的颜色产生变化的因素都可能会导致history color变得无效。
2. History Color失效后的处理
当history color失效后,我们需要对这种情况进行相应的处理。一种处理方法是丢弃history color,然后直接使用当前帧的颜色作为最终的颜色。然而,该方法会导致pixel失去反走样效果。
另一种处理方式是使用neighborhood clamping方法来进行处理。该方法的基本思想是通过当前帧pixel的一个邻域范围内的像素,来在颜色空间中构造一个颜色范围,然后将history color的大小限制在该范围之中。该方法的基本的假设是——某个pixel反走样后的颜色基本与该pixel邻域范围内pixel颜色的blending结果相同。如果该假设成立,则将history color限制在邻域pixel构成的颜色范围中是一种正确的做法。然而,当pixel中存在sub-pixel feature时,该假设无法成立。
Neighborhood Clamping方法中首先需要根据pixel的邻域颜色来构建一个颜色空间范围,如果我们使用凸包来构造一个颜色空间范围,则我们可以获得一个最小的颜色空间范围。然而,该方法过于复杂,容易造成效率问题。
另一种构造颜色范围的方法是使用axis-aligned bounding box(AABB)。通过使用pixel的邻域颜色来构建一个AABB,则可以构造出一个较紧的颜色范围。并且,我们可以将pixel的颜色从RGB颜色空间转换到YCoCg空间后,再在YCoCg颜色空间构造一个AABB。这是因为YCoCg颜色空间能够体现颜色的亮度差异。
当history color不在AABB范围中时,一种处理方式是将history color进行clamping,即
另一种处理方式是使用cliping操作,即计算pixel和history color所连接形成的线段与AABB的交点。相比较于clamping操作而言,cliping得到的颜色是pixel和history color的一个插值,与pixel的颜色更相似。
3. Flicking问题
在使用neighborhood clamp方法后,场景中可能会有pixel的闪烁问题。即使当相机与物体静止,pixel的闪烁问题依然可能存在。导致闪烁发生的主要原因在于,场景中存在sub-pixel feature,从而导致neighborhood clamp方法的基本假设无法成立。举一个例子来对该情况进行说明。

如图 2 所示,previous frame的pixel的颜色为红色,并且其邻域颜色构成的AABB中的,。假设previous frame的历史颜色为红色,则经过neighborhood clamp操作处理后,history color依然为红色,则最终的结果为红色。在current frame时,由于sample的变化,导致当前的pixel颜色变为白色,并且邻域颜色构成的AABB中的,,经过neighborhood clamp操作处理后history color变为白色,则最终经过blending后的颜色为白色。通过上面简单的例子可以看出,当场景中存在sub-pixel feature时,即使在静态场景下,像素颜色也会存在帧间变化从而导致闪烁问题的发生。
4. 模糊问题
Temporal Antialiasing算法存在的另一个问题是模糊问题。当使用了TAA算法后,渲染出来的图片可能会存在一些模糊。导致该问题的原因主要有以下三个:
- 使用了错误的mipmap level
- reprojection diffusion
- 对无效的history color进行blending
由于mipmap level与图片的分辨率有关,且temporal antialiasing算法在每一帧中采样pixel中的一个sample,从而导致在计算mipmap level时使用的分辨率是屏幕的分辨率。然而,由于temporal antialiasing算法与super sampling算法类似,实际上在计算mipmap level时应该使用super sampling的分辨率,从而导致mipmap的level计算错误。Mipmal level的计算错误可以通过对计算得到的mipmap level增加一个bias来解决。
Reprojection diffusion问题的产生是由于对history buffer进行重采样从而导致的。在对history buffer进行重采样时,采样的位置可能并不在history buffer中的像素中心位置,从而导致采样得到的颜色是对history buffer重构的结果,即是插值出来。该插值出来的像素由于不是一个正确的像素颜色,而是插值出来的,则该插值出来的history color则带有一些模糊的效果,从而会导致blending了该history color的pixel具有模糊效果。并且,由于history buffer是不断累积的,会更加剧这个问题。解决该问题的一个方法是使用更好的重构方法来代替线性插值方法,来使得插值出来的pixel更加锐利。例如,使用Catmull-Rom插值方法来进行插值。
与混合了插值出来的history color类似的原因。当history color无效时,最终的pixel由于混合了无效的history color,也会导致blending后的pixel带有模糊的效果。
另外,为了减轻TAA导致的模糊问题,我们可以通过为当前帧得到的颜色纹理增加一个sharepen filter来减轻该问题。