战争迷雾开源库测评

战争迷雾开源库测评

【博物纳新】是UWA旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性。很多时候,我们并不知道自己想要什么,直到某一天我们遇到了它。

更多精彩内容请关注:lab.uwa4d.com


开源库链接:
https://lab.uwa4d.com/lab/5b5642f6d7f10a201fd8df39

一、前言

战争迷雾在实际军事战争中通常是指:由于对敌人情报不清楚,而无法确认除友军所在地以外的大部分地区的敌人分布及活动情况。在游戏领域,战争迷雾也常被用来模拟真实军事战争中的情况。尤其是即时战略以及MOBA类游戏中,它是增加游戏战略多样化以及趣味性的重要元素。

战争迷雾最早被用于游戏,是在一款即时战略游戏《沙丘2》中。每当玩家开始新的一局对战时,玩家只能观察到自己基地及单位周围极小的范围,而绝大多数地图区域均被黑色遮盖。当玩家命令己方部队向黑暗区移动后,经过区域的迷雾会自动消散,地图变得可见,包括该区域的地形、敌人活动情况等等。这一经典模式也被绝大多数后来的即时策略游戏和MOBA游戏继承。


二、实现原理

本文接下来将要介绍的是基于Unity引擎的一种战争迷雾实现方法。该方法的主要思路是:首先,将场景在XZ平面分成均匀的方格。并用一个二维数组记录每块方格区域的可见性。然后,根据己方单位的位置、以及可见范围,计算场景中可见的方格,并记录下来。接着,利用该可见性数据,生成一张记录了可见性区域的纹理,并对该纹理进行模糊等操作。最后,将该纹理通过图像后处理绘制到屏幕上。下图显示了该项目的运行时截图:

请输入图片描述

如上图所示,其中左上方红色方框显示的场景渲染的结果。场景中绿色胶囊体表示己方单位,红色胶囊体表示地方单位。黑色不可见区域为迷雾笼罩区域,可见区域为迷雾消失区域。当迷雾消失时,场景中的物体以及地方单位都变为可见。右下方绿色方框显示的是战争迷雾数据可视化结果。其中,黑色部分表示没有被己方单位探索过的区域,红色区域表示已经被己方单位探索过的区域,灰色区域表示当前己方单位所在周围可见的区域,绿色区域表示当前更新可见数据时新增的可见区域。

上图中的四个灰色区域表示了四个己方单位在朝着不同方向探索地图,下图动态地展示该效果:
请输入图片描述


三、使用方式与具体实现

3.1 使用方式
该项目使用非常简单,主要涉及到的脚本组件有三个:

  • FogOfWarEffect.cs
  • FogOfWarExplorer.cs
  • FogOfWarStalker.cs

FogOfWarEffect:该脚本组件需要挂载在主相机上。参数设置如下图所示:
请输入图片描述

其中,FogMaskType是用于设置计算可见区域范围的方式,可选项有:Basic、Accurate、以及Circlar。剩下的参数包括:设置方格区域大小,纹理分辨率、模糊效果的参数以及shader。具体含义可参考工程代码,本文不再赘述。

FogOfWarExplorer:该脚本组件需要挂载在己方单位上。参数设置如下图所示:
请输入图片描述

其参数比较简单,仅包含一个可见区域范围半径。

FogOfWarStalker:该脚本组件需要挂载在敌方单位上。其主要作用是根据战争迷雾的可见性,计算并设置该对象的可见性。

3.2 具体实现
当FogOfWarExplorer组件挂载到己方单位上后,在每一帧的Update函数中调用FogOfWarEffect.UpdateFOWFieldData函数来更新当前的可见性数据:
请输入图片描述

计算当前可见性数据时,采用了多线程的方式,利用ThreadPool.QueueUserWorkItem函数进行异步计算:
请输入图片描述

计算结束后立刻对存储可见性数据的Mask纹理进行更新:
请输入图片描述
(详细代码可参考:FogOfWarExplorer.cs,FOWMap.cs等)

在渲染迷雾时,将存储可见性数据的Mask纹理传入Shader。然后,根据相机视域体的位置计算屏幕上每个像素在Mask纹理上的纹理采样坐标,并进行采样。最后,将结果叠加到场景中。
(详细代码可参考FOWRenderer.cs)

四、性能测评

最后,UWA惯例是一定要关注性能数据的,在OPPO A59s、三星S6、小米8三个不同机型上使用UWA GOT Online分别进行了一分钟左右的测试,得到三台设备上的帧率数据如下图:
请输入图片描述

当然这个例子中,还有相当一部分渲染耗时是和战争迷雾效果无关的。所以接下来以三星S6的数据为例,具体查看报告中的代码效率耗时情况。
请输入图片描述

首先关注的是渲染耗时Camera.Render这一项,除了不透明渲染地形与主角的耗时之外,发现Camer.ImageEffects这一项的耗时也比较明显,占了总体耗时的42%。联系上文此项目的实现方式可知这一项对应的是迷雾纹理通过图像后处理绘制到屏幕上的操作。
请输入图片描述

如上图所示,Camera.ImageEffects的耗时大约在4~7ms的范围内波动,部分高值与Camera.Render的整体高值重合。

再来关注一下逻辑代码部分的相关耗时,可以在逻辑代码函数列表中,找到与FogOfWar相关的几个逻辑代码耗时均值统计得到如下表格:
请输入图片描述

从以上统计中,可以大致得出战争迷雾相关的逻辑在不同机型上的耗时表现。这里注意到后处理用到了OnRenderImage,且耗时较高,建议在实际使用时,参考Unity引擎后处理性能优化方案解析一文进行优化。

今天的推荐就到这儿啦,或者它可直接使用,或者它需要您的润色,或者它启发了您的思路......

请不要吝啬您的点赞和转发,让我们知道我们在做对的事。当然如果您可以留言给出宝贵的意见,我们会越做越好。