unity hdrp的TAA

入口

当hdrp开启了后处理后会执行PostProcessSystem.cs的Render,然后如果开启了taa则执行taaEnabled中的内容

获取历史和申请当前颜色rt,获取历史移动速度和当前移动速度rt

GrabTemporalAntialiasingHistoryTextures主要收集历史颜色rt和申请当前颜色rt的。

GrabVelocityMagnitudeHistoryTextures主要是收集历史速度变化rt和当前速度变化rt的。

TAA核心

DoTemporalAntialiasing这里是核心的taa的处理,taaParams主要是收集一些taa需要的参数,比如前面说的rt。

通过DrawProcedural渲染两个pass,都是属于Hidden/HDRP/TemporalAA中的pass。

颜色处理

第一个pass是主要处理taa的地方。

首先顶点着色器中对进来的图片进行全屏的uv和位置信息获取

核心是片元着色:

首先要获取最接近当前深度信息的附近的深度GetClosestFragment,原理是通过周围的四个像素获取深度值得到最接近当前深度的,加上这个深度值。

用这个值来对速度rt“_CameraMotionVectorsTexture”采样,这样得到的是一个基于摄像机移动后的速度变量。

有了这个速度变量motionVector,用当前的uv减他就是前一帧的uv了。

然后如果需要过滤可以通过GetFilteredHistory来过滤,他可以用HistoryBilinear来线性过滤前后值或者用HistoryBicubic5Tap来通过五张历史图片来得到过滤,这个方法来源于smaa。

亮度为关键因素

然后会让历史颜色乘PerceptualWeight,PerceptualWeight主要是获取亮度信息,通过YCOCG图片的x通道或者通过Luminance提取亮度都可以。

然后通过Fetch4获取当前颜色以及周边四到八个颜色信息。然后通过FilterCentralColor来获取均值,相当于模糊了一次。

然后执行GetNeighbourhoodCorners获取周围最大亮度和最小亮度以及他们的平均亮度,有两种方式获取,一种是直接看最大最小的MinMaxNeighbourhood

另一种是通过求方差来获取VarianceNeighbourhood

闪烁问题

获取的最大最小亮度来裁剪历史颜色信息GetClippedHistory。这里的目的是减少前后帧混合时的闪烁,鬼影等问题。

然后通过SharpenColor来获取线性颜色信息。filteredColor = SharpenColor(samples, filteredColor, sharpenStrength);

再通过GetBlendFactor来计算混合的系数,通过历史亮度以及周边最大最小的亮度得到混合系数。

半透明计算

如果要计算半透明,会用混合系数GetBlendFactor来获取历史颜色和当前颜色的alpha混合。然后颜色上也要跟alpha关联的变化

然后考虑是否需要tonemap,因为历史颜色混合会导致之前的颜色信息有所丢失,所以最后做一次tonemap会让颜色信息恢复。

最后再把当前颜色以及速度rt当作历史颜色和速度rt,让下次执行时可以获取历史颜色。

抖动颜色处理

第二个pass就是做一些抖动颜色处理

缓存

最后的PoolSource这里主要就是通过hash做值来保存渲染后的rt。

另外这里有一篇说ue的TAA,跟unity的做法相似,有部分不同。TAA原理及OpenGL实现 - 知乎

猜你喜欢

转载自blog.csdn.net/llsansun/article/details/123469972