Temporal Anti-Aliasing (TAA)
时间上的反走样。
一帧取左上角,
一帧取右上角,
一帧取右下角,
一帧取左下角,
就相当于当前帧做了四倍的超采样。
- 为什么不随机而使用固定的样本?
因为随机会额外引入一些高频信息。
- 如果场景运动了怎么办?
考虑场景运动的物体在上一帧的哪个像素。用motion vector。
SSAA 与 MSAA
SSAA 基于超采样,严格掉帧率的。SSAA4倍就会掉到差不多1/4帧率。
MSAA 四倍不见得会掉到1/4。
MSAA 在一个像素里有多个感知样本,同一个三角形上的多个样本只做一次shading。然后加权混合。
MSAA 允许做sample reuse,在空间上。两个像素共同边界上的点采样一次可以当作采样了两个像素上的点。
基于图像的反走样
把图像中的锯齿提取出来,然后反走样得到没有锯齿的图。
Enhanced subpixel morphological AA (SMAA)
最流行的方法。
历史:FXAA -> MLAA -> SMAA
矢量化方法。
720p 1080p 只要1ms。
G-Buffer是不能反走样的
有意义的数值不能反走样,图像可以反走样。
Temporal Super Resolution (Temporal Super Sampling)
目标:增加图像分辨率
会想到DLSS,把低分辨率的图变成高分辨率的图。
DLSS1.0:没有任何额外信息,全靠猜;那么对于每个游戏每个场景单独训练一个神经网络,这个神经网络会学习常见的物体边缘,争取把小的图拉大之后把模糊的边缘换成不模糊的边缘。
DLSS2.0:利用temporal的信息,用TAA的方法。面临的巨大问题,一旦有temporal failure就不能再用clamping来解决问题了。对temporal信息的利用要求更严格了。猜出来的像素更像周围的点,就会很糊,分辨率变大了却没有对内容的细化。
对比 双三次插值 和 DLSS2.0
双三次插值 540p->1080p:模糊
DLSS2.0 540p->1080p:和原生的1080pTAA差不多
DLSS2.0为什么可以做的这么好?
关键在于提升神经网络跑的速度,给NVIDIA的硬件做做优化,闫大作为DLSS的合作伙伴也不知道,属于最高机密。
DLSS其实AMD也有:Fidelity FX Super Resolution
DLSS其实Facebook也山寨了一个,发了篇paper:Neural Supersampling for Real-time Rendering [Xiao et al.] 更像DLSS1.0
题外话:AMD的Cpu很值,同样的性能,AMD一半价钱。
Deferred Shading 延迟渲染
延迟渲染是一种节省shading时间的方法
先从光栅化过程开始谈起,把不同的三角形打散成fragment,然后经过深度测试,通过之后做shading 写到pixel。很有可能每一个fragment都要做shading,什么情况下每个fragment都要做shading?从远的开始渲染,一直渲染到近的,这样每个fragment都会通过深度测试。
最复杂的情况下,每个fragment都要shade一遍,有多个light的话,还要对每个fragment考虑多个light。
Deferred Shading的思想:我们只去shade可见的fragment。
要把场景光栅化两次,
第一次:只光栅化得到fragment,不做shading。更新深度缓存。
第二次:这次已经存了深度测试的fragment,可以确保通过深度测试的fragment都是能够看到的fragment。
前提是,我们认为shade一次fragment开销非常大,rasterize一次场景开销非常小。
Tiled Shading 建立在Deferred Shading的基础上
节省光源的计算时间
把屏幕分成小块,每个小块32x32。把3D空间拆成一条一条的。
- 每个小块单独做shading。
节省每个小块要考虑的光源的数量
前提:点光源、面光源平方衰减,导致覆盖范围很小,所以超出一定的范围可以忽略不计。可以看作每个光源覆盖的范围都是固定的球型。
不见得所有光源都会影响到这个条,只要求相交就可以了。
Clustered Shading 建立在Tiled Shading基础上
不仅把屏幕分成若干块,还要在深度上进行切片。
把3D空间切成了网格。
- 场景中光源的贡献是有限的,切成长条范围很大,会覆盖很多光源。但是不见得对切成的小块有贡献。
Level of Detail Solutions
类似 texture的MIPMAP
在计算的时候只要选择一个正确的level去节省计算量
-
shadowmap
实际使用的时候会生成多种shadowmap
近处用准确的shadowmap,远处用粗糙的shadowmap。
近处的生成一个分辨率高,覆盖范围小的shadowmap,远处生成一个分辨率相同,但是覆盖范围大的shadowmap。
根据物体在场景中的哪个位置,选取使用哪一张shadowmap。
在切换shadowmap层级的时候会出现突变,在两张shadowmap重叠的部分进行混合(blend)。 -
LPV
格子的划分,密集和稀疏 -
geometric LoD
通过和摄像机的距离,告诉渲染管线我要渲染什么精细度的模型。
但是按这样的方法,还是会出现突变的情况。这个就叫popping artifacts
这种情况可以交给TAA处理,起到平滑的作用。
这就是UE5的Nanite。
Nanite就是动态选取detail的做法。
根本没有用到compute shader,所以是自己写了套光栅化的管线。
一个物体不同的部位要使用不同的层次结构,比如一座高楼,一部分离视线近一部分离视线远。 -
虚拟纹理的实现
对一个理论上无限大纹理的调度。用另一种几何的表示方法,几何纹理来表示几何。就可以实现LoD对几何层级的混合。
Global Illumination Solutions
先做SSR得到一个近似的GI
SSR不行的地方再用其他方案来弥补,用硬件或者软件做ray tracing。
-
软件做ray tracing,近处物体需要高质量的SDF,远处用低质量的SDF把所有场景覆盖到。
如果场景里有非常强的方向光源和点光源,比如手电筒(RSM)
3D场景中分布很多个probe(探针)会记录一些irradiance,再用这些probe去照亮场景。(DDGI) -
硬件做ray tracing,用简化的模型去代替原始的模型
也可以用RTRT的思路结合probe的思路(RTXGI) -
UE5 的 Lumen的实现方案就是
先做SSR得到一个近似的GI
软件做ray tracing,近处物体需要高质量的SDF,远处用低质量的SDF把所有场景覆盖到。
如果场景里有非常强的方向光源和点光源,比如手电筒(RSM)
硬件做ray tracing,用简化的模型去代替原始的模型
需要补充的知识点
SDF贴纹理很难,怎么贴
透明物体渲染顺序怎么办
粒子渲染partical rendering
后期处理(镜头光斑,运动模糊,景深)
随机数种子和蓝噪声
凹凸不平的渲染 foveated rendering
VR应用,盯着的地方投入更多算力。