<前段时间接触了一些代理Lod的东西,用到了UE4的HLOD(Hierarchical Level of Detail),就顺便扒了下Epic他们这方面的文章,结合堡垒之夜里面的技术,简单的总结一下。

Proxy LOD Tool(代理Lod),是在ue4.20的版本中加进来的,这个工具在移动平台上优势巨大。Proxy LOD工具的大概工作流程是,通过降低由于多边形数、绘制调用和材质复杂性,提高性能,可以省内存,省带宽,在低端机器上尤为重要。而在做PC和主机优化时,Proxy LOD也提供了显著的收益。

这篇文章中,我们来了解下Epic的TA和程序是怎么用巧妙的方法实践LOD的,以堡垒之夜《Fortnite Battle Royale》(FNBR)为例。

构建和破坏的一致性

玩过Fortnite的都知道,游戏中你经常会面临各种建筑的构建和破坏。而在匹配游戏中,Fortnite是可以跨平台匹配的,这时候更要保证不同平台的公平性。为了做到这一点,Fortnite团队必须想出一种方法来减少绘制调用的数量或同时显示在屏幕上的对象的数量,来解决构建和销毁可能带来的性能问题。

模块化世界

为了更好地理解构建和破坏所带来的问题,您首先需要了解FNBR中的建筑是如何构建的。在Fortnite中看到的每一栋建筑都是由一系列Modular pieces组成的,这些模块可以快速地“拼接”在一起,形成任何需要的结构。

这种模块化的构建方法可以减少所需的资源的数量,节约内存,节约空间。这是因为你可以用不同的材料和纹理以不同的方式重用不同的模块。

图片左侧的整个建筑,仅使用图片右侧的九个StaticMesh构建。以这种方式生成的建筑好处也十分明显,就是玩家在拆墙的时候,只需要破坏对应的部分就可以了,破坏的部分禁用渲染和碰撞。

虽然这种显示破坏的方法在PC和主机上都很好用,但在性能较弱的移动设备上确实存在一些问题。

就是Fortnite中一个建筑物可能有3,400个独立部分,如下的动图

可能PC和主机完全hold住,但对于移动平台来说就不行了,可能整个场景组件数都不能过千。

现在我们对建筑物是如何整体创建有了一点了解,那么让我们来看看每个组件是如何构建的,因为在后面显示带破坏的HLOD的时候也会用到。

为啥要用LOD

即使使用了Fortnite中使用的模块化结构,但是跑不掉你的设备还是有个同屏绘制的上限(Draw call),这个上限受硬件的制约。在不同平台上玩Fortnite,可以支持的DrawCall肯定是不一样的。为了确保每个平台都有平滑和稳定的帧率,Fortnite中使用的每个StaticMesh都包含多个详细级别(LOD)Mesh。 说白了就是场景中的静态物体,距离相机一定距离时,它会显示一个低模的版本,节约资源。

上面的图片显示了同一个模型不同级别的LOD,从左往右依次是LOD0~LOD3,可以看到Trangles的数量下降的很明显。随着相机离墙越来越远,不同的LOD就会显示出来。具体看下面的动图,其实随着距离的增大,还是很难看出差距的。

关于如何从一个多三角面的Mesh变成一个低三角面的Mesh,这里我们需要去了解下低级别的LOD在生成的时候发生了什么。

最后一个级别的LOD是怎么生成的

使用ue4的静态网格编辑器打开一个StaticMesh,默认显示的是最后一个LOD级别网格。

可以看到这里的Triangles是12,Vertices是18。

但是如果你用三维软件创建一个Cube,导到ue4中,会发现Triangles和Vertices却是12和24(6个面,每个面2个三角形)这多出来的6的顶点看着不多,但是如果这个组件在某个建筑上用了100次,就是600个顶点,10个建筑就是多6k个顶点。这6k的顶点确是完全可以省掉的。

所以这些模块化的静态网格做了如下调整:

1. 禁用Smoothing Groups

每个可以支持模块化的部件都不使用Smoothing Groups平滑组。

2.静态网格UV的设置

使尽可能少的UV Island。

关于UV island是个啥,我查了点资料,网上说的也不是很清楚,如果有人知道是个啥,恳请告诉我一下

好像意思是,有的模型2个不同的面,没有共用顶点,他2个不同的面就会是高对比度,因为面的法向量不同,如果重叠的顶点删掉了,共用顶点就会是平滑过渡的,像island一样平滑过渡。

对于这个模块块,盒子的正面和背面映射到整个0~1 UV空间。然后,周围的部分,所有焊接在一起,并按比例匹配目前的模块件的设置。

3.法线处理

修改法线以确保尽可能减轻垂直面上的任何平滑伪影。

左图左边的点是重叠顶点三个方向的阴影,右边的点是合并之后,产生的伪影子。右图是调整法线之后的效果。

当这三步做完之后,新的Model被导出替换原有的。

这个过程也是最后一个LOD级别的工作流程。

HLOD

现在,构成某个建筑的所有模块部件都有了LOD,这些LOD可以是模型用尽可能少的三角形表达,然后使用UE4 的HLOD(层次详细工具)生成该建筑的新版本,如下图所示

而这个HLOD到底干了啥呢。

其实他把整个建筑使用LOD3级别的Mesh,合并生成了一个Proxy代理,这个代理也是一个StaticMesh和纹理,这样做的好处就是,你都使用LOD3了,想必是离得很远的,那个还绘制3,400个组件不划算。不如直接合成一个StaticMesh画出来。

这大大减少了显示建筑物所需的三角形数量,将三角形数量从50820个减少到2880个。对手机等低端设备而言,这是一个巨大的进步。这个新版本的建筑将只显示在低端设备上,而且只有当玩家距离建筑30米左右时才会显示。这也有助于减少建筑使用的材料的数量。

HLOD利大于弊

在玩Fortnite的时候,你可能会发现,当你看远处的建筑时,看不到破坏的墙面的破洞 。这是因为你看到的是最后一个LOD是使用代理几何工具生成的Proxy。

虽然这个这个建筑没有显示玩家造成的破坏,但是他降低了远离摄像机的建筑的渲染成本。当在本例中的这个建筑物的HLOD版本,从2880个三角形减少到只有412个三角形。下图是412 三角形的样子,效果虽然很惨,但是毕竟离得远呀~

看看动图的效果,效果还是很可以的。

带破坏的HLOD(关键部分)

前面说了那么多,大概知道HLOD是啥,Proxy是啥了,但是还有个问题,就是最低一级的HLOD不带破坏是没啥问题的,可是HLOD1,HLOD2呢,希望他有LOD,又希望他可以显示破坏。

Epic的TA他们是这么操作的:

  • 1.向所有使用的BuildingWall类的建筑物添加一个名为HLODDestructionIndex的新属性。
  • 2.在构建HLOD时,将为建筑物使用的每个Actor分配一个Index,index写入顶点色。
  • 3.每个建筑物基础将需要一个足够大的RenderTarget,保证每个可破坏组件都有一个纹理。
  • 4.使用HLOD就行网格合并,并将自定义顶点颜色用于新生成的静态网格物体。
  • 5.当建筑物的一部分,如墙壁被破坏时,读取HLODDestructionIndex值,然后将黑色写入这个Index对应的texel。
  • 6.在材质中,使用填充到顶点颜色中的ID,并使用它来查找销毁纹理,然后如果texel读取为零(销毁部分),则将顶点塌陷到原点,就等于隐藏了。

他们这种做做法,等于其实没有改变网格的状态,而是通过改变渲染状态来达到显示破坏的效果。

而在脚本层,通过发出一个类似像素被破坏的事件。

以上就是Epic TA他们原型阶段做的工作,后面已经交给工具程序员变成一个真正的生产工具。

UE4 Proxy的演示

大概的流程演示一下,具体说明可以参考官方文档

  • 1.world setting里打开HLOD.
  • 2.windows窗口开启Hierachical LOD Outliner
  • 3.点击GenerateClusters,生成Clusters
  • 4.点击GenerateProxyMeshes生成代理
  • 5.到场景中验证代理是否正常

可以看到GenerateClusters之后,生成了5个LODActor,下一步就是生成ProxyMeshes

选中某个LODActor,在detail面板可以看到,他的StaticMesh已经是被合成一个的。

最后再导实际场景中看一下。camera 离远点,果然LOD,加载的已经变成我们的Proxy代理了。

版权声明:本文为匿名原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: