GAMES202-高质量实时渲染(Real-Time Ray-Tracing)
目录
- RTX
- 降噪
- 时间滤波
- Back projection
- 滤波实现
- 空间滤波
- 高斯滤波
- 双边滤波(考虑边界)
- 联合双边滤波
- RTRT滤波解决方案
- SVGF
- RAE
- 工业界问题及解法
- TAA 时间上的抗锯齿
- MSAA vs SSAA
- SMAA
- 超级分辨率
- 延迟渲染
GitHub主页:https://github.com/sdpyy1
作业实现:https://github.com/sdpyy1/CppLearn/tree/main/games202
RTX
RTX实际做的事:
一个像素用一个样本来采样SPP
考虑了一次弹射,第一次primary Ray其实没有必要(从摄像机到着色点),只需要做一遍光栅化就可以实现一整个屏幕的primaryRay。所以一个SPP只需要考虑3条光线
降噪
时间滤波
1SPP噪声非常大。实时光线追踪在算法上并没有区别,主要原因是硬件的突破,让光线追踪达到了实时水平。所以实时光线追踪最关键的技术是降噪!
从这幅图可以看出,降噪的效果非常好。降噪的方法有很多,但是应用到实时的降噪技术很少
实时降噪使用的是时间上的滤波。当前帧需要前一帧已经滤波。假设运动是连续的。有一个vector叫做motion vector,记录每个点上一帧的位置
也就是当前帧用的spp,使用了上一帧的spp,上一帧的spp也用了上上帧的spp,所以作用到当前帧的spp,远大于1。
下面首先介绍一个概念,G-buffer,这东西就是延迟渲染用的
Back projection
求一个像素的内容,在上一帧中的位置
首先求一个点的世界坐标:
- 可以提前存储在G-buffer
- 通过MVP+viewport的逆变换变回世界坐标
- 我们是知道每个世界坐标是如何变换的,所以通过逆变换来找到这个坐标上一帧的坐标,再把世界坐标转为屏幕坐标即可
得到上一帧对应像素的像素值,进行线性插值,通常a取0.1-0.2,也就是80%以上都是上一帧得到的
下面对比一下groundtruth和降噪结果
有一些该暗的地方仍然是亮的。
基于时间的滤波是有问题的,有一下几点:
-
第一帧/切换场景
-
当前帧的物体在上一帧不存在
-
- 当前帧的物体在上一帧被遮挡了(G-buffer中没有存储)
会出现脱尾
- 当前帧的物体在上一帧被遮挡了(G-buffer中没有存储)
解决思路:
- 混合当前帧和上一帧数据之前,把上一帧的结果拉到当前帧周围
- 检测要不要用上一帧的数据
- 检测上一帧位置是否为同一个物体
- 优化混合系数
- 增大空间滤波
但是这样处理噪声又出现了
滤波实现
空间滤波
滤波操作为低通滤波,保留低频信息,移除高频信息
高斯滤波
双边滤波(考虑边界)
高斯滤波会把图像均匀地糊掉,边界也会模糊 ,公式的第二项表示如果两边颜色差值很大,贡献就会变小
联合双边滤波
使用G-buffer来更好地指导滤波
用深度、颜色、法向量来指导滤波
如何实现大的滤波核呢?先水平再垂直,效率从
Progressively Growing Sizes
RTRT滤波解决方案
SVGF
3个factors指导的滤波
- 深度
- 法线
- 颜色差异
RAE
工业界问题及解法
TAA 时间上的抗锯齿
每一帧采样一个像素的四个角之一,剩余三个角用之前的数据。这样就相当于MSAA了(静止场景)
MSAA vs SSAA
SSAA就是高分辨率渲染再变小
MSAA分辨率不变,在一个像素中采样多次,甚至可以在临近像素复用
SMAA
超级分辨率
延迟渲染
节省shading的时间