以前记录的文章。
雾是一种让远处几何渐隐的图形技术。早期的游戏引入了雾来隐藏在远处渲染的几何图形。即使在不再需要它之后,游戏仍然支持fog,因为它增加了场景的真实性,减少了draw call的数量,因为完全在fog中的几何体可以被剔除。
在Cesium中,雾是大气颜色和地平线上地形的混合。部分处于雾中的地形瓦片会增加其屏幕空间误差(SSE),这样可以渲染低分辨率的地形。完全在雾中的瓦片将被完全剔除,甚至不被请求。
这些优化将地平线视图中渲染的瓦片和从服务器请求的瓦片的数量都减少了35%。
性能比较
这是一个高3600米、俯仰角-15度的山景:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mXhTdTlf-1688263163600)(https://cesium.com/blog/images/2015/11-12/mt-enabled.jpg#id=KILWm&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=260)] | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xhzilo24-1688263163601)(https://cesium.com/blog/images/2015/11-12/mt-diff.jpg#id=Zek1A&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=260)] | |
---|---|---|
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwXRDWBG-1688263163602)(https://cesium.com/blog/images/2015/11-12/mt-disabled-tiles.jpg#id=XPmaA&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=260)] | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2WUoiLK-1688263163602)(https://cesium.com/blog/images/2015/11-12/mt-enabled-tiles.jpg#id=Vxs21&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=260)] | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UF2vGWm8-1688263163603)(https://cesium.com/blog/images/2015/11-12/mt-diff-tiles.jpg#id=V08YH&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=260)] |
关闭雾 | 开启雾 | |
渲染瓦片: 327 | 渲染瓦片: 228 | |
请求瓦片: 510 | 请求瓦片: 322 | |
FPS: 115 | FPS: 155 |
在第一行的第三列显示使用雾时的视觉差异。对于许多应用程序,用户并不关注远处的地形,所以这种差异在最坏的情况下是不明显的,在最好的情况下是更有视觉吸引力的。
在第二行的第三列显示了由于雾而被剔除的远处瓷砖的可视化。可以看出,其中许多瓦片根本不可见。
这是在490米的高度和俯仰角在0度的俯视图:
关闭雾 | 开启雾 | |
渲染瓦片: 401 | 渲染瓦片: 284 | |
请求瓦片: 530 | 请求瓦片: 302 | |
FPS: 118 | FPS: 150 |
Fog类的注意点
对于那些能让相机更接近地面并能看到地平线的应用,雾可以通过两种特性来调节:浓度(density)和屏幕误差系数(screenSpaceErrorFactor)。density
是[0.0,1.0]
范围内的一个标量,以指数方式改变雾的起始和结束距离。screenSpaceErrorFactor
线性地增加了地形的屏幕误差,因为与相机的距离增加,部分被雾遮挡。
fog里面定义了heightsTable
和densityTable
,这两个表是通过对某些视图的雾浓度进行抽样,并找出在哪一点上进行瓦片剔除能够影响地平面视图而得出的。在场景更新的时候,根据相机高度,从heightsTable
中找出对应的索引,进而从densityTable
表中的浓度区间进行插值,得到的此高度下的浓度值。
如何影响地形瓦片的加载
首先了解一下QuadtreePrimitive中的maximumScreenSpaceError
变量,它代表着最大屏幕空间错误(SSE,以像素为单位,默认为2)。较高的maximumScreenSpaceError
将会渲染更少的贴图,进而可以提高性能,而较低的值将提高视觉质量。
在cesium选择瓦片的时候,会计算每个瓦片的SSE,若小于maximumScreenSpaceError,就会进行渲染。
if (screenSpaceError(primitive, frameState, tile) < primitive.maximumScreenSpaceError) {
// 该瓦片符合SSE要求,所以渲染它。
if (tile.needsLoading) {
// 以中等优先级加载符合SSE的瓦片。
primitive._tileLoadQueueMedium.push(tile);
}
addTileToRenderList(primitive, tile);
return;
}
而在计算瓦片的SSE的时候,会检查fog是否开启,若开启则会进行如下计算:
CesiumMath.fog = function(distanceToCamera, density) {
var scalar = distanceToCamera * density;
return 1.0 - Math.exp(-(scalar * scalar));
};
if (frameState.fog.enabled) {
error = error - CesiumMath.fog(distance, frameState.fog.density) * frameState.fog.sse;
}
这样在开启fog后,error值就会比之前减小。当density越大时候,从fog公式中可以看出,得出的值越大,那么最终计算出的SSE就会越小,这就是为什么开启fog之后,地形瓦片请求次数减少的原因。