先贴一个UE4 TAA的slide
https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf

里面细节问题很多,先记录一下目前想到和遇到的问题,便于备忘,后面有空的话再记录。

TAA用到的Velocity和抖动对精度要求比较高, 特别是大场景下误差容易比较大,UE4做了一系列的处理来保持精度。

投影矩阵的精度

 1     static const FMatrix InvertProjectionMatrix( const FMatrix& M )
 2     {
 3         if( M.M[1][0] == 0.0f &&
 4             M.M[3][0] == 0.0f &&
 5             M.M[0][1] == 0.0f &&
 6             M.M[3][1] == 0.0f &&
 7             M.M[0][2] == 0.0f &&
 8             M.M[1][2] == 0.0f &&
 9             M.M[0][3] == 0.0f &&
10             M.M[1][3] == 0.0f &&
11             M.M[2][3] == 1.0f &&
12             M.M[3][3] == 0.0f )
13         {
14             // Solve the common case directly with very high precision.
15             /*
16             M =
17             | a | 0 | 0 | 0 |
18             | 0 | b | 0 | 0 |
19             | s | t | c | 1 |
20             | 0 | 0 | d | 0 |
21             */
22
23             double a = M.M[0][0];
24             double b = M.M[1][1];
25             double c = M.M[2][2];
26             double d = M.M[3][2];
27             double s = M.M[2][0];
28             double t = M.M[2][1];
29
30             return FMatrix(
31                 FPlane( 1.0 / a, 0.0f, 0.0f, 0.0f ),
32                 FPlane( 0.0f, 1.0 / b, 0.0f, 0.0f ),
33                 FPlane( 0.0f, 0.0f, 0.0f, 1.0 / d ),
34                 FPlane( -s/a, -t/b, 1.0f, -c/d )
35             );
36         }
37         else
38         {
39             return M.Inverse();
40         }
41     }

可以看到对投影矩阵的取反做了特殊处理,来提高浮点计算精度。

视图矩阵的精度

1     FVector DeltaTranslation = InPrevViewMatrices.GetPreViewTranslation() - InViewMatrices.GetPreViewTranslation();
2     FMatrix InvViewProj = InViewMatrices.ComputeInvProjectionNoAAMatrix() * InViewMatrices.GetTranslatedViewMatrix().GetTransposed();
3     FMatrix PrevViewProj = FTranslationMatrix(DeltaTranslation) * InPrevViewMatrices.GetTranslatedViewMatrix() * InPrevViewMatrices.ComputeProjectionNoAAMatrix();
4
5     ViewUniformShaderParameters.ClipToPrevClip = InvViewProj * PrevViewProj;

将视图矩阵的位移和旋转拆开来(T*R),以避免大地图上,相机位置过大造成的误差。

Reprojection是把当前帧Clip space或NDC space的点重新投影到上一帧的位置

Reprojection = (V*P)-1 * (PrevV*PrevP)

=  P-1 * V-1 * PrevV * PrevP

其中V为视图矩阵,P为投影矩阵。

而UE4的视图矩阵实际使用TR的方式 (类似变换矩阵的TRS和RTS的顺序,区别是试图矩阵没有缩放, https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/why-transformation-order-is-significant

注意如果是相同的T和R, T*R和R*T结果是不一样的,这里的TR,是在ViewMatrix结果一样的前提上,拆解出的另外两个矩阵,从几何分析的角度也可以得出)

Reprojection = P-1 * (T*R)-1 * (PrevT*PrevR) * prevP

= P-1 * R-1 * T-1 * PrevT * PrevR * PrevP

= P-1 * R-1 * (T-1 * PrevT) * PrevR * PrevP

其中:
Reprojection是UE4代码里的ViewUniformShaderParameters.ClipToPrevClip,
R是ViewMatrix的旋转部分(UE4代码中的GetTranslatedViewMatrix),
T是ViewMatrix的位移部分,

T-1*PrevT 就是UE4代码中的 FTranslationMatrix(DeltaTranslation) 。

这样做的好处是,把两个绝对位置转换为一个相对位移, 从而避免绝对位置过大而导致的矩阵Inverse的精度问题。

同时,视图矩阵的旋转部分 R 是正交矩阵,所以Transpose等价于Inverse,这样不仅是效率的提高,更重要的是避免了Inverse导致的浮点误差。

VelocityBuffer的精度

 1 // for velocity rendering, motionblur and temporal AA
 2 // velocity needs to support -2..2 screen space range for x and y
 3 // texture is 16bit 0..1 range per channel
 4 float2 EncodeVelocityToTexture(float2 In)
 5 {
 6     // 0.499f is a value smaller than 0.5f to avoid using the full range to use the clear color (0,0) as special value
 7     // 0.5f to allow for a range of -2..2 instead of -1..1 for really fast motions for temporal AA
 8     return In * (0.499f * 0.5f) + 32767.0f / 65535.0f;
 9 }
10 // see EncodeVelocityToTexture()
11 float2 DecodeVelocityFromTexture(float2 In)
12 {
13     const float InvDiv = 1.0f / (0.499f * 0.5f);
14     // reference
15 //    return (In - 32767.0f / 65535.0f ) / (0.499f * 0.5f);
16     // MAD layout to help compiler
17     return In * InvDiv - 32767.0f / 65535.0f * InvDiv;
18 }

VelocityBuffer在TAA里用来reproject移动的物体,包括蒙皮动画和位移旋转动画等。

为了提高精度,VelocityBuffer可以使用Float32。Unity使用的是Float16x2 (R16G16F), 不同的是,UE4使用的是INT16x2 (R16G16_INT)。
对于Float16,最小精度是2-10。 如果映射到Int16,去掉等价的符号位,精度是2-15。 这样在占用同样显存大小的情况下,提高了精度。

转载于:https://www.cnblogs.com/crazii/p/7215298.html

[工作积累] UE4 TAA ReProjection的精度处理相关推荐

  1. php之工作积累 (一)

    php之工作积累 (一) 前言:在每天的工作中都能看到不少新东西,遇到这种情况我都是百度一下,然后记到记事本上以备不时之需,然而昨晚电脑突然死机让我感觉这样不太靠谱,如果这些都没了,那我最近的积累就都 ...

  2. 工作积累(五)——使用spring@Value注解实现常量功能

    之前的博客中提到过如何通过 java.util.ResourceBundle 和 java.util.Properties 类通过读取 key-value 文件的形式实现常量功能.其实 spring ...

  3. 工作积累⑨——从丁香医生增长看地推的重要性

    工作总结系列目录: 工作总结③--数据分析师到底该如何分析? 工作积累⑥--从留存下降看小红书的精细化运营 工作积累⑦--从新零售和漏斗模型解读亚马逊增长策略 工作积累⑧--从星巴克送外卖看新零售的线 ...

  4. 工作积累⑦——从新零售和漏斗模型解读亚马逊增长策略

    工作总结系列目录: 工作总结③--数据分析师到底该如何分析? 工作积累⑥--从留存下降看小红书的精细化运营 工作积累⑧--从星巴克送外卖看新零售的线下战争 工作积累⑨--从丁香医生增长看地推的重要性 ...

  5. [工作积累] TAA Ghosting 的相关问题

    因为TAA要使用上一帧的历史结果,那么在相机移动的时候,颜色就会有残留,出现ghosting(残影). 由于上一帧历史是累积的,是由上一帧的直接渲染结果和上上帧的结果做了合并,所以ghosting并不 ...

  6. [工作积累] 大型世界的草渲染

    最近工作在研究如何在大型世界的植被(主要是草)的渲染,主要考虑下面几个问题: 1.半自动化procedual生成,密度分布,画刷 2.受环境的的影响(风,角色等) 3.LOD和动态加载释放 由于睡觉后 ...

  7. 【基础积累】目标检测NMS—精度提升篇

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要10分钟 Follow小博主,每天更新前沿干货 作者:曲終人不散丶 知乎链接:https://zhuanlan.zhihu.com/p/151 ...

  8. [工作积累] shadow map问题汇总

    1.基本问题和相关 Common Techniques to Improve Shadow Depth Maps: https://msdn.microsoft.com/en-us/library/w ...

  9. 程序员新人面临最尴尬的事:需要工作积累经验,需要有经验才能找到工作!到底怎么办?...

    你需要一份工作来积累经验,但你需要有经验才能找到工作-- 大学刚毕业,或者转换职业方向后新入一个职场领域,你会发现求职之路举步维艰.大多数的公司职位都要求工作经验,单这一点就足以将你拒之门外. 前几天 ...

最新文章

  1. MySQL的优化(大纲)
  2. 单网段DHCP服务器的架设
  3. 【机器学习】聚类代码练习
  4. UOJ #590. 天天和树
  5. python显示图像某列的颜色值_Python Pandas Matplotlib图由单列中定义的类型值着色
  6. mysql hibernate id generator_Hibernate映射文件id的generator配置方法
  7. 扩展模块 php.ini_php相关的配置,PHP动态扩展模块
  8. 采油工计算机试题库,数字化采油工试题库.doc
  9. 机器学习的挑战:黑盒模型正面临这3个问题
  10. “性能监视器”监视系统性能的基本设置
  11. jeecg3.8popup弹出窗口触发失去焦点事件,引发验证弹窗,影响体验问题的解决办法
  12. vi/Vim的快速使用
  13. 想搞定大厂面试官?4面阿里拿到P7Offer通用流行框架大全
  14. 语言百马百担求马匹数_C语言经典编程题(下)
  15. 机器学习数学基础(1)-回归、梯度下降
  16. Linux并非无毒 十五年病毒简史
  17. pycharm专业版账号登录问题
  18. 数据结构实验项目二:栈的基本操作及其应用
  19. python多项式求导_OO博客作业1:多项式求导作业总结
  20. windows11没有ie浏览器解决办法

热门文章

  1. 小知识-美元石油体系
  2. NLP《语言模型(三)-- 基于循环神经网络的RNNLM语言模型》
  3. unity3d 取锚点位置_周三手机课实时共享位置,方便朋友找到见面地点
  4. Python语法入门
  5. 逻辑回归能摆平二分类因变量,那……不止二分类呢?
  6. Multi-thread--C++11中thread的使用
  7. Ubuntu16.4 将python3.5重新切换为python2.7后,pip运行出错
  8. 卡尔曼滤波原理(二):扩展卡尔曼
  9. MySQL之User(用户)和Privilege(权限)
  10. DCIC巡游车与网约车运营特征对比分析-数据读取