UE4的HLOD代理浅谈
<前段时间接触了一些代理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组成的,这些模块可以快速地“拼接”在一起,形成任何需要的结构。
这种模块化的构建方法可以减少所需的资源的数量,节约内存,节约空间。这是因为你可以用不同的材料和纹理以不同的方式重用不同的模块。
![](https://pic4.zhimg.com/v2-276f37b911163537e5e2cb43ba43401b_b.jpg)
![](https://pic4.zhimg.com/80/v2-276f37b911163537e5e2cb43ba43401b_hd.jpg)
图片左侧的整个建筑,仅使用图片右侧的九个StaticMesh构建。以这种方式生成的建筑好处也十分明显,就是玩家在拆墙的时候,只需要破坏对应的部分就可以了,破坏的部分禁用渲染和碰撞。
虽然这种显示破坏的方法在PC和主机上都很好用,但在性能较弱的移动设备上确实存在一些问题。
就是Fortnite中一个建筑物可能有3,400个独立部分,如下的动图
![](https://pic2.zhimg.com/v2-e692394d3cd09bc6814ba4686777684d_b.gif)
![](https://pic2.zhimg.com/v2-e692394d3cd09bc6814ba4686777684d_b.jpg)
可能PC和主机完全hold住,但对于移动平台来说就不行了,可能整个场景组件数都不能过千。
现在我们对建筑物是如何整体创建有了一点了解,那么让我们来看看每个组件是如何构建的,因为在后面显示带破坏的HLOD的时候也会用到。
为啥要用LOD
即使使用了Fortnite中使用的模块化结构,但是跑不掉你的设备还是有个同屏绘制的上限(Draw call),这个上限受硬件的制约。在不同平台上玩Fortnite,可以支持的DrawCall肯定是不一样的。为了确保每个平台都有平滑和稳定的帧率,Fortnite中使用的每个StaticMesh都包含多个详细级别(LOD)Mesh。 说白了就是场景中的静态物体,距离相机一定距离时,它会显示一个低模的版本,节约资源。
![](https://pic1.zhimg.com/v2-65d0031146d3b0687f16be58c628e670_b.jpg)
![](https://pic1.zhimg.com/80/v2-65d0031146d3b0687f16be58c628e670_hd.jpg)
上面的图片显示了同一个模型不同级别的LOD,从左往右依次是LOD0~LOD3,可以看到Trangles的数量下降的很明显。随着相机离墙越来越远,不同的LOD就会显示出来。具体看下面的动图,其实随着距离的增大,还是很难看出差距的。
![](https://pic1.zhimg.com/v2-f9882eb2370605b561c045fee30b99f4_b.gif)
![](https://pic1.zhimg.com/v2-f9882eb2370605b561c045fee30b99f4_b.jpg)
关于如何从一个多三角面的Mesh变成一个低三角面的Mesh,这里我们需要去了解下低级别的LOD在生成的时候发生了什么。
![](https://pic2.zhimg.com/v2-db9257ac6c5993676eed0c0297292d2d_b.jpg)
![](https://pic2.zhimg.com/80/v2-db9257ac6c5993676eed0c0297292d2d_hd.jpg)
最后一个级别的LOD是怎么生成的
使用ue4的静态网格编辑器打开一个StaticMesh,默认显示的是最后一个LOD级别网格。
![](https://pic4.zhimg.com/v2-db6cd774db99239a75e87cfa1bf5d9cb_b.jpg)
![](https://pic4.zhimg.com/80/v2-db6cd774db99239a75e87cfa1bf5d9cb_hd.jpg)
可以看到这里的Triangles是12,Vertices是18。
但是如果你用三维软件创建一个Cube,导到ue4中,会发现Triangles和Vertices却是12和24(6个面,每个面2个三角形)这多出来的6的顶点看着不多,但是如果这个组件在某个建筑上用了100次,就是600个顶点,10个建筑就是多6k个顶点。这6k的顶点确是完全可以省掉的。
![](https://pic1.zhimg.com/v2-0a12b8f310af8980fe2d3d865fdbba54_b.jpg)
![](https://pic1.zhimg.com/80/v2-0a12b8f310af8980fe2d3d865fdbba54_hd.jpg)
所以这些模块化的静态网格做了如下调整:
1. 禁用Smoothing Groups
每个可以支持模块化的部件都不使用Smoothing Groups平滑组。
![](https://pic3.zhimg.com/v2-734bf844ddbf62eba62fbde8ddda3e82_b.jpg)
![](https://pic3.zhimg.com/80/v2-734bf844ddbf62eba62fbde8ddda3e82_hd.jpg)
2.静态网格UV的设置
使尽可能少的UV Island。
关于UV island是个啥,我查了点资料,网上说的也不是很清楚,如果有人知道是个啥,恳请告诉我一下
好像意思是,有的模型2个不同的面,没有共用顶点,他2个不同的面就会是高对比度,因为面的法向量不同,如果重叠的顶点删掉了,共用顶点就会是平滑过渡的,像island一样平滑过渡。
对于这个模块块,盒子的正面和背面映射到整个0~1 UV空间。然后,周围的部分,所有焊接在一起,并按比例匹配目前的模块件的设置。
![](https://pic4.zhimg.com/v2-aba3340a25f6cf85822e5e91963941d7_b.jpg)
![](https://pic4.zhimg.com/80/v2-aba3340a25f6cf85822e5e91963941d7_hd.jpg)
3.法线处理
修改法线以确保尽可能减轻垂直面上的任何平滑伪影。
![](https://pic3.zhimg.com/v2-ff636e7db5cfaf2d2d9dc81ca7d0959e_b.jpg)
![](https://pic3.zhimg.com/80/v2-ff636e7db5cfaf2d2d9dc81ca7d0959e_hd.jpg)
![](https://pic4.zhimg.com/v2-5bc3437c0615f5b75238933cdcba1ac7_b.jpg)
![](https://pic4.zhimg.com/80/v2-5bc3437c0615f5b75238933cdcba1ac7_hd.jpg)
左图左边的点是重叠顶点三个方向的阴影,右边的点是合并之后,产生的伪影子。右图是调整法线之后的效果。
当这三步做完之后,新的Model被导出替换原有的。
这个过程也是最后一个LOD级别的工作流程。
HLOD
现在,构成某个建筑的所有模块部件都有了LOD,这些LOD可以是模型用尽可能少的三角形表达,然后使用UE4 的HLOD(层次详细工具)生成该建筑的新版本,如下图所示
![](https://pic3.zhimg.com/v2-4cf1be8fd38d3db3e1649d1e3f9d414a_b.jpg)
![](https://pic3.zhimg.com/80/v2-4cf1be8fd38d3db3e1649d1e3f9d414a_hd.jpg)
而这个HLOD到底干了啥呢。
其实他把整个建筑使用LOD3级别的Mesh,合并生成了一个Proxy代理,这个代理也是一个StaticMesh和纹理,这样做的好处就是,你都使用LOD3了,想必是离得很远的,那个还绘制3,400个组件不划算。不如直接合成一个StaticMesh画出来。
这大大减少了显示建筑物所需的三角形数量,将三角形数量从50820个减少到2880个。对手机等低端设备而言,这是一个巨大的进步。这个新版本的建筑将只显示在低端设备上,而且只有当玩家距离建筑30米左右时才会显示。这也有助于减少建筑使用的材料的数量。
HLOD利大于弊
在玩Fortnite的时候,你可能会发现,当你看远处的建筑时,看不到破坏的墙面的破洞 。这是因为你看到的是最后一个LOD是使用代理几何工具生成的Proxy。
虽然这个这个建筑没有显示玩家造成的破坏,但是他降低了远离摄像机的建筑的渲染成本。当在本例中的这个建筑物的HLOD版本,从2880个三角形减少到只有412个三角形。下图是412 三角形的样子,效果虽然很惨,但是毕竟离得远呀~
![](https://pic2.zhimg.com/v2-79955cd6cc0ee22a7fdf13d40f9b3a61_b.jpg)
![](https://pic2.zhimg.com/80/v2-79955cd6cc0ee22a7fdf13d40f9b3a61_hd.jpg)
看看动图的效果,效果还是很可以的。
![](https://pic1.zhimg.com/v2-c0df7d8c9cd07de64b0a2ce5d4e5c5c8_b.gif)
![](https://pic1.zhimg.com/v2-c0df7d8c9cd07de64b0a2ce5d4e5c5c8_b.jpg)
带破坏的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读取为零(销毁部分),则将顶点塌陷到原点,就等于隐藏了。
他们这种做做法,等于其实没有改变网格的状态,而是通过改变渲染状态来达到显示破坏的效果。
而在脚本层,通过发出一个类似像素被破坏的事件。
![](https://pic1.zhimg.com/v2-860d7e44f8d00c8248c79189135466b8_b.gif)
![](https://pic1.zhimg.com/v2-860d7e44f8d00c8248c79189135466b8_b.webp)
以上就是Epic TA他们原型阶段做的工作,后面已经交给工具程序员变成一个真正的生产工具。
UE4 Proxy的演示
大概的流程演示一下,具体说明可以参考官方文档
- 1.world setting里打开HLOD.
- 2.windows窗口开启Hierachical LOD Outliner
- 3.点击GenerateClusters,生成Clusters
- 4.点击GenerateProxyMeshes生成代理
- 5.到场景中验证代理是否正常
![](https://pic3.zhimg.com/v2-7d20c5eb28e2e2354bbf2b723c579d16_b.jpg)
![](https://pic3.zhimg.com/80/v2-7d20c5eb28e2e2354bbf2b723c579d16_hd.jpg)
![](https://pic1.zhimg.com/v2-638473c0c1385b9a5d6a66e19d34d9c4_b.jpg)
![](https://pic1.zhimg.com/80/v2-638473c0c1385b9a5d6a66e19d34d9c4_hd.jpg)
可以看到GenerateClusters之后,生成了5个LODActor,下一步就是生成ProxyMeshes
![](https://pic2.zhimg.com/v2-87fb60edc19ca47eec7ede980b45f845_b.jpg)
![](https://pic2.zhimg.com/80/v2-87fb60edc19ca47eec7ede980b45f845_hd.jpg)
选中某个LODActor,在detail面板可以看到,他的StaticMesh已经是被合成一个的。
![](https://pic1.zhimg.com/v2-36f101b7fe96ac2adfdb20b23af002dc_b.jpg)
![](https://pic1.zhimg.com/80/v2-36f101b7fe96ac2adfdb20b23af002dc_hd.jpg)
最后再导实际场景中看一下。camera 离远点,果然LOD,加载的已经变成我们的Proxy代理了。
![](https://pic2.zhimg.com/v2-b6c4fac90c0d38673467387391a1b9c9_b.gif)
![](https://pic2.zhimg.com/v2-b6c4fac90c0d38673467387391a1b9c9_b.jpg)
UE4的HLOD代理浅谈相关推荐
- 浅谈云函数的代理IP利用面
浅谈云函数的代理IP利用面 前言 本篇文章介绍如何通过 Serverless(云函数) 实现各种扫描器探测功能,以达到绕过态势感知.WAF等安全设备,增大蓝队研判人员溯源难度,实现封无可封,查无可查的 ...
- 浅谈模式 - 代理模式
真实动作的前面和后面分别做一些行为.真实动作使用委托的方式来调用. 静态代理 public interface Subject {void buyTicket(); } public class Su ...
- 什么是proxy服务器代理?怎么设置代理服务器?浅谈服务器代理与VPN的区别
服务器 服务器是计算机的一种,它比普通计算机运行更快.负载更高.价格更贵.服务器在网络中为其它客户机(如PC机.智能手机.ATM等终端甚至是火车系统等大型设备)提供计算或者应用服务.服务器具有高速的C ...
- 浅谈Android中的MVP与动态代理的结合
浅谈Android中的MVP与动态代理的结合 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在Android开发平台上接触MVP足足算起来大概已经有一个年头左右.从最开始到现在经 ...
- 浅谈几种区块链网络攻击以及防御方案之拒绝服务攻击
旧博文,搬到 csdn 原文:http://rebootcat.com/2020/04/14/network_attack_of_blockchain_ddos_attack/ 写在前面的话 自比特币 ...
- iOS实录15:浅谈iOS Crash
导语:在当前的iOS开发中,虽然ARC为开发者解决了手动内存管理时代 的许多麻烦,但是内存方面的问题依然是产生iOS Crash的元凶之一,本文介绍内存方面,有关僵尸对象.野指针.内存泄漏.废弃内存这 ...
- 浅谈Service Mesh体系中的Envoy
摘要: 提到Envoy就不得不提Service Mesh,说到Service Mesh就一定要谈及微服务了,那么我们就先放下Envoy,简单了解下微服务.Service Mesh以及Envoy在Ser ...
- 【转】浅谈.net remoting 与webservice
1. .NET Remoting .NET Remoting是微软随.NET推出的一种分布式应用解决方案,被誉为管理应用程序域之间的 RPC 的首选技,它允许不同应用程序域之间进行通信(这里的通信可以 ...
- 浅谈以太坊智能合约的设计模式与升级方法
浅谈以太坊智能合约的设计模式与升级方法 1. 最佳实践 2. 实用设计案例 2.1 控制器合约与数据合约: 1->1 2.2 控制器合约与数据合约: 1->N 2.3 控制器合约与数据合约 ...
最新文章
- 【内推】滴滴出行视觉计算组招聘算法实习生
- ext form验证tip_FormValidator表单验证
- springMVC 不扫描 controller 中的方法
- 将网页保存为webarchive文件的代码
- 介绍一个前端页面开发必备神器,chrome扩展,设备模拟器
- java 静态线程_Java线程类静态本机void yield()方法(带示例)
- 同样做前端,为何差距越来越大?
- 1949:【10NOIP普及组】数字统计
- 理解CNN中的特征图 feature map
- 未给员工足额缴纳公积金!董明珠曾豪言:每人一套房不需要公积金
- QQ音乐播放地址 API
- python怎么填充背景颜色,python通过pil为png图片填充上背景颜色的方法
- 批量获取百度网盘文件目录
- c语言棋盘光标怎么删除,删除光标前的字符按什么键
- 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)
- 清北学堂 2017-10-05
- macbook新建html文件,New File Creation: 给 Mac 加上“新建文件菜单”
- MySQL之正则表达式
- dbcp2数据源配置详解
- 宝塔部署Yii框架多个商城项目,队列问题“服务测试失败,请检查服务是否正常运行”
热门文章
- Linux中硬连接(hard link)与软连接(symbolic link)的区别
- 非常简单的animation动画
- win10计算机未连接到网络适配器,windows10系统下网络适配器显示未连接如何解决...
- 【ABAP】创建局部Macro和全局Macro
- 【精品】pinia详解
- Eclipse中server配置Tomcat显示红色方块并报Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web
- Xenserver上连接NFS服务器时RPC:portmapperfailure;PRC:Unable to recieve
- 网页定时自动截图实现方法
- 基于QT和UDP Socket实现的即时通信软件
- js中获取元素的当前位置