发光物体通常更能吸引人们的注意力;
在可视化应用中,普遍会用发光来标记重要物体、定位重点区域、划定重要范围等;
发光效果是场景的重要组成部分,对场景整体美观度有着重要的影响。
为此,我们在WebGL产品中,对泛光效果做了多次迭代,力求得到更好的效果,更优的性能,更精细的控制。
通用泛光效果的实现方案:
(1)获取原始纹理图像(泛光后处理前,从渲染管线中输出的纹理);
(2)对原始纹理进行提取“待泛光部分图像”的预处理;
(3)对预处理后得到的纹理进行模糊;
(4)将步骤(1)和步骤(3)的结果纹理进行再融合。
以上就是一个通用的泛光效果实现流程。
对于B点(如何提取图片中泛光的部分),目前普遍的做法是采用HDR或类似颜色方案,通过设定一个阈值,来统一提取画面中明亮的部分作为泛光要素,因此泛光要素的亮度必须足够高(大于设定的阈值)才行。
泛光范围可影响的相邻像素足够多(即泛光效果的扩散);
非泛光部分和泛光部分的明暗对比明显。
通常情况下的做法:如果想要提升泛光范围,则需要增大模糊半径来实现。
而增大模糊半径会带来两个负面影响:
一个是增加性能负荷。后处理范围变大,必然导致性能降低;
会使得明暗对比变弱。因为滤波进行加权平均时,弱化了中心亮度,因此普通泛光方案的效果较差。
要扩大光晕范围,本质上就是查询原纹理上更大范围内的纹素信息,然后进行加权平均。
然而单纯在原始纹理上扩大滤波盒范围,会增加采样次数从而增加性能负担。
而通过借鉴Mipmap技术:
(1)不同于普通方案,晶石WebGL中采用两张原始纹理输出(泛光后处理前,由渲染管线输出两张纹理,一张为正常要素纹理,一张是需要泛光的纹理);
(2)对原始待泛光纹理进行降采样,得到更高级别的纹理(像素数量更少的纹理);
(3)同时,在更高级别的纹理上使用更大范围的滤波盒。
与通用的方案相比,可以在有效减少采样次数的同时,实现扩大光晕范围的效果。
Mipmap技术是一种纹理映射技术,根据距观看者远近距离的不同,以不同的分辨率将单一的材质贴图以多重图像的形式表现出来并代表平面纹理。
下图以4 x 4像素纹理举例:
假设原始纹理尺寸128 x 128。
滤波盒尺寸设为5,则采样次数为:128² x 5²=409600,随着原始纹理尺寸越大它的影响越大,次数越多。
先对纹理进行降采样,得到128 / 2 x 128 / 2,即64 x 64的新纹理。
滤波盒尺寸为5时,对新纹理进行采样,次数为:64² x 5²=102400,采样次数比普通方案减少了4倍左右,对于高分辨率大纹理时的性能提升更明显。
假设此时为了获得更大的光晕效果,扩大滤波盒尺寸到7,则采样次数为:64² x 7²=200704,仍然比普通方案中滤波盒尺寸为5时的采样次数少。
(1)为了让泛光有层次感,借鉴UE泛光方案,将纹理降采样五次;
(2)针对步骤A中的每一级纹理,分别进行x和y轴的模糊(即与每一级对应滤波相乘);
(3)所有级别纹理模糊后的结果进行最终合并;
(4)将模糊合并后的纹理再与原始图像进行叠加,获得最终结果。