本文首发在“内核工匠”微信公众号,欢迎关注公众号获取最新Linux技术分享。
FSR 是空间滤波算法,分成EASU和RCAS两部分。EASU是边缘适配的空间上采样(Edge Adaptive Spatial
(资料图)
Upsampling),RCAS是健壮对比度适配锐化(Robust Contrast Adaptive Sharpening),从CAS发展而来。
Lanczos 采样及多项式拟合
FSR 使用了 Lanczos2 函数:
a是Lanczos的核大小,蓝色是a=2,绿色是a=时的曲线,a越小,变化越剧烈,高频滤波的效果越强
FSR EASU使用多项式进行拟合,省去了sin,平方根等耗时的计算:
其中 ω用来移动控制窗口大小。下图叠加了多项式和Lanczos2的图像,可以看到当 在附近时,拟合效果较好。
EASU 算法主要流程
分析FsrEasuF()函数,可知EASU算法主要流程:
采样周围12个点,计算各点亮度 以内部2x2的四个点为中心的"+"字型为单位,进行4次计算,使用双线性插值得到梯度和长度 对梯度,长度等量做校准,为下一步做呗参数 根据方向进行旋转,通过 计算Lanczos2函数的波形,得到权重 权重和颜色的混合纹理采样
采样12个点b,c,e,f,g,h,i,j,k,l,n,o, 形状如下:
算法的输入是屏幕空间整型坐标,进行中心对齐。p0,p1,p2,p3点是归一化的纹理空间坐标,在[0,1]之间,它们作为textureGather的输入坐标进行采样。由于每一次只采一个颜色通道,所以总共有4x3=12次textureGather调用。算法以f为假想的基准点,F为其左上角整数坐标点。(Vulkan纹理坐标t轴向下)
亮度的计算比较简单,使用 ∗ r + ∗ b + g ,突出绿色通道的作用,值域在 [0, 2]
计算特征
FsrEasuSetF()函数被调用四次,每一次处理一个"+"字型:
为了和代码保持一致,这里用s,t,u,v标记每次调用的中心2x2 quad的四个点之一:
s t
u v
wi ∈[ s , t , u , v ]是中心点落在s,t,u,v四种情况下的权重,公式如下:
它的分配方式是:
每一次调用输入5个点的亮度值,使用a,b,c,d,e统一标记位置之间的相对关系如下:
则方向矢量 dir 的计算仅使用水平和垂直相邻方向,不考虑对角线,+字型中心点也不参与计算:
以水平方向为例,考虑下三种亮度变化的情形,显然1型具有较强的方向性,而3型梯度变化过于剧烈,被忽略。
长度是个标量,单次调用的计算方式如下:
经过四次FsrEasuSetF 函数调用,实际上 dir和l都做了双线性插值。
数值校准
特征F和Lanczos拟合多项式控制因子ω的映射关系
代码流程
12点加权平均
FsrEasuTapF函数实现了每个点的颜色计算,累积起来就是12个点的加权平均。函数原型和一个典型的调用方式:
void FsrEasuTapF(
inout AF3 aC, // Accumulated color, with negative lobe.
inout AF1 aW, // Accumulated weight.
AF2 off, // Pixel offset from resolve position to tap.
AF2 dir, // Gradient direction.
AF2 len, // Length.
AF1 lob, // Negative lobe strength.
AF1 clp, // Clipping point.
AF3 c)
AF2 v;
= ( * ()) + ( * );
= ( * (-)) + ( * );
旋转公式:
计算最终颜色
EASU 总结
EASU实际上使用了统一的公式处理了边缘和非边缘像素。非边缘像素周边像素接近,加权平均;边缘像素变化较大,做高频滤波,使用Lanczos2函数,实际也是加权平均,只不过权值是负值。假设当前像素是P,P点对应输入图像的像素为Q,以上处理过程实际是这样一个抽象的加权平均算法:
其中 W ( Qi )的是Q点周围点的权值,使用Lanczos2拟合多项式计算,效果和Bicubic接近,但是性能较好,用了12个点(Bicublic 16个点)。
RCAS
在EASU放大后,RCAS做锐化,使用的模板为:
它是拉普拉斯算子的变种,这里w为负半轴权重。输出像素计算公式:
那么 w 如何计算? RCAS 根据周围像素的对比度来计算。
首先得到+字型的亮度最大值 M 和最小值 m,则 w 的公式为:
其中Scale为上采样之后的分辨率与原分辨率的比值。
移植和优化
FSR 1 画质效果一般,但即便如此,移动端延迟也偏高,高帧率的游戏是不适用的,需要进行优化。这篇文章提到了不少的优化方向可供借鉴:
/posts/optimizing-fsr/
可以找到代码 github 找到源码, 总结起来有以下几点:
使用半精度 减少纹理采样次数,考虑只采一个通道 提前退出 移除deringring 计算四次 FsrEasuSetF 然后插值改成先插值输入再调用一次 FsrEasuSetF,减少大量计算关键词:
相关的文章>>
热门搜索:
资讯
更多图说健康
更多疏风解毒胶囊的作用与功效是什么?疏风解毒胶囊可以起到解毒利咽...
艾叶的功效与作用有哪些?1、散寒止痛艾叶为菊科蒿属植物艾的叶...
治疗白发的偏方有哪些?1 桑白皮30克,五倍子15克,青葙子60...
紫癜性肾炎是什么病?所谓的紫癜性肾炎,就是由于患者对于某些东...
维生素ad是什么?维生素AD是指维生素A和D的混合制剂,是两种脂溶...
乙肝小三阳严重吗?乙肝小三阳有些比较严重,也有些不太严重的,...
常见疾病
更多体育健身
更多邓云霄(约1613年前后在世),字玄度,东莞人。明朝官员。万历...
根据《仪征市2023年公开招聘公益性岗位工作人员公告》规定,经...
(文凯。)华声在线全媒体记者黄欣然 通讯员王怡瑾8月中旬,中...
我很愿意充当一个百科达人,对「难堪」这个关键词进行解答。为...
为激发企业研发创新动力,提升企业“研值”,江北区还开展企业...
■济宁口腔医院李洪涛牙周病是指炎症或细菌引起的牙周组织疾病...