施主分享随缘,评论随心,@author:白袍小道

小道暗语:

1、因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了。标题格式大致都是(原or转) 二级目录 (标题)

2、因为所看和以前记录太过杂乱,所以只能手动一点点搬移(回忆,整理)。欢迎讨论,知识和能力总是被问出来了不是(嘿嘿,这样才能成长), 若有不对别喷就好哈哈。

引言:

文章四方面包括了从游戏线程渲染线程GPU内存等的优化,提升游戏技术底子。

原作者:王祢,Epic Games 资深开发者技术支持,管理虚幻引擎技术支持的程序员团队,拥有近15年虚幻引擎使用经验。

正文:

优化肯定是有个前提和需求背景的,本文的前提:在移动设备上做大地型的多人游戏。

需求背景:

1、开放地图:视野宽,视距远,地图大

2、场景:风格变化多

3、同屏人不少

4、交互也不少

(看到这里对吧,UE +上述 就直接说堡垒之夜就好了呗)

渲染线程

.1

场景遍历

场景的复杂度(渲染前有场景遍历哦,其他地方详细说了比如关卡,primitive搜索,叉树,等等等)嘿嘿

渲染线程的第一个开销取决于场景的复杂度,即使实际绘制出来的内容很少,但是场景遍历的开销却是正比于场景

在内存里的Primitive数量的。

如果我这个遍历时间很长,那么实际绘制调用发出的时间就会比较晚。这个时候,我们就要利用好Streaming Level来最小化Scene Tranversal的开销。另外,动态的对象每一幀重新获取要绘制的渲染数据,也会有不小的开销,同时也会降低静态对象的渲染状态排序的优势。这也是上面提到过的加入了特殊的Static Render Path的优化手段的原因。

.2

裁剪

.3

DrawCall

(刷,HLOD来合并,实例)

剔除完就到了最终头的开销来源:Draw Calls,减少DC的手段多种多样,譬如引擎提供了刷foliage的工具,对于石头、树之类大量复用的对象,用这种方式刷出的HISCM,会做gpu instancing大大减少DC数。

然后一个有用的方案是HLOD,可以把一组Mesh甚至是一个关卡合并成一个Proxy Mesh,在最低级LOD后,可以切换到这个合并的Mesh,大大的减少远处物件的Draw Call并依然保持很远的视距。HLOD依然可以做多级的LOD帮助进一步减少DrawCall和减少面数,这些工具都是引擎内建,可以很方便部署自动化。

Dynamic Instancing,我们有一些特殊的方案,也做了一些整合,接下来的引擎版本会有非常大的渲染pipeline的重构(信不信),会对这个有更天然支持,甚至支持带光照烘焙的Dynamic Instancing,在光照图计算的时候就把可以instancing到一起的对象优先并到一张光照图上。

.4

Drawing Policies

另外一个和DrawCall开销息息相关的是渲染状态切换的数量,引擎里有个接近的概念叫Drawing Policies,刚才说静态的对象我们会按Drawing Policies分组排序,现在的版本中,我们针对这个分组排序的规则做了一些改进,可以更好的减少渲染线程的渲染绘制调用的状态切换,同时也一定程度兼顾gpu的overdraw

刚才说到的新的mesh draw command pipeline要到今年年底,明年年初才上线,在目前的测试场景中,对于渲染线程的优化,可能有近十倍的改善,当然最终在移动端上表现如何还不能下定论。整个新管线的思路是尽可能使得渲染线程在cpu端没有什么开销的,场景资源管理等的开销都在GPU上。

.5

RHI Thread

[可以看看UERender模块,队列命令和线程

在OpenGL ES上,GraphicAPI的调用必须和glcontext在一个线程,于是,我们把所有的gl command都enqueue到了一个叫RHI Thread的线程,这样一来,实际渲染驱动的开销和引擎渲染线程的工作就可以有一部分并行化,减少整个渲染的frame time,以及变向降低渲染线程所在核的主频,这样可能在部分设备上还能减少一些功耗开销。

Hitches

Loading

当启用streaming level异步加载以后,如果游戏逻辑发生了阻塞加载,由于引擎并不知道加载数据的依赖性,所以会导致引擎Flush异步线程,造成卡顿。其中普通游戏逻辑触发的加载我们可以比较容易的察觉并改正,但是另一个情况是在网络同步的时候,当服务器第一次同步回来一个新的Actor时,客户端会创建Actor Channel(UE网络提出了同步的有关的几个Channel),并需要实际Spawn Actor,可能会依赖阻塞加载的数据,进而导致flush造成卡顿。

我们可以通过打开net.AllowAsyncLoadingEnabled,使得触发的加载变成一个异步加载,并且这个Actor Channel的创建过程,也会加入一个pending的队列,等到加载资源都到了以后的那帧才可以实际的创建。

CompileShader

由于OPGLES没有固定的shadercache标准,引擎提供了ShaderCache,在新版本中改进成了ShaderPipelineCache的功能,该系统可以在离线环境下先跑一遍游戏,在这个过程中用到的Shader,绘制的状态记录都会在Log文件中。Runtime的时候,我们会先读log,分一些批次预先Compile完以减少runtime发生compile的情况。

另外,一旦compile,可以配合另一个ProgramBinaryCache的功能,引擎会把link完的program保存下来,以后再需要加载Shader的时候,如果发现这个link program存在,会直接加载program。

这样不但能省去compile和link的过程,还跳过了shader code的加载过程和节省了内存。除了compile,这个cache系统还会做warmup,也就是预先绘制,以减少第一次使用的额外开销。

Spawing

Cook,池,C++组件,蓝图组件(序列化优化)

降低spawn的开销一个是减少每个components的数量,再者,尽可能用C++的Component。如果你是BP components,引擎项目设置中有一个选项,可以在cook的时候把components的序列化,初始化的结果存下来,spawn的时候直接拿这个数据做实例化就行了。

然后Component注册到游戏线程可以做分时。当然最常规的减少spawn卡顿的方法还是做pooling,如果有大量同类型Actor的Spawn,建议这样做。

4

GC

引用分析,Destroy会分幀去做

GC主要分为两步,先是引用分析,然后分析完标记可以destruct的对象会在这时开始发出BeginDestroy,而实际的Destroy会分幀去做,因为有些对象渲染线程的资源还在访问,不能当场删掉,所以只是发出一个render fence,渲染线程回收掉,我们才在下一帧主线程purge的阶段把对象删掉。

在整个GC过程中最费的,是引用分析,因为这个必须在当前这幀做完,新版本中我们把标记和引用分析都做了多线程并行,利用所有的核计算,可以比较好的提高引用分析的效率。还有一种手段是可以跳过大量的常驻内存的对象,我这里列了一个参数,MaxObjectNotConsideredByGC,设置这个参数范围内的对象是不会在引用分析的时候做检测的。

再有一点是Clustering,一组对象永远是共生的,可以规划在Clustering里面,这样的场景下GC效率可能提升十几倍。最后新版本中,我们把BeginDestroy也放到的发生GC的后一帧去做。

(转\整)UE4游戏优化 多人大地型游戏的优化(二)渲染线程的优化的更多相关文章

  1. (转\整)UE4游戏优化 多人大地型游戏的优化(一)游戏线程的优化

    施主分享随缘,评论随心,@author:白袍小道 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题) 2.因 ...

  2. (转\整)UE4游戏优化 多人大地型游戏的优化(四)内存的优化

    施主分享随缘,评论随心,@author:白袍小道,当苦无妨 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题 ...

  3. (转\整)UE4游戏优化 多人大地型游戏的优化(三)GPU的优化

    施主分享随缘,评论随心,@author:白袍小道 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题) 2.因 ...

  4. WP老杨解迷:如何营造让人花钱的游戏

    游戏是最好做也是最不好做的项目,游戏的好坏现在都是直接从数据来说话,Windows Phone的游戏应用同样不可能逃出这个行业准则,要说在市场里做的好,那就直接拿数据来说,几乎没人会去在乎游戏到底传达 ...

  5. 《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇06:移动版优化指南》--本系列完结

    6.移动版优化指南 概述: 移动设备不同于目前的高端设备(Wii.Xbox 360和PS3),市场上的手机硬件是很有限的,并且所有的移动设备都是不一样的.像Adroid手机,由于品牌和出厂年限的不同, ...

  6. day23 02 组合(继续人狗大战游戏)

    day23 02 组合(继续人狗大战游戏) 面向对象的三大特性:继承 多态 封装 先讲解一下组合 组合:一个对象的属性值是另一个类的对象:对象.属性.属性(一般有两个点) 继续扩展day22 01里面 ...

  7. Unity5.1 新的网络引擎UNET(七) UNET 单人游戏转换为多人

     单人游戏转换为多人   孙广东   2015.7.12 本文档描写叙述将单人游戏转换为使用新的网络系统的多人游戏的步骤.这里描写叙述的过程是简化,对于一个真正的游戏事实上须要更高级别版本号的实际 ...

  8. 如何构建一个多人(.io) Web 游戏,第 2 部分

    原文:How to Build a Multiplayer (.io) Web Game, Part 2 探索 .io 游戏背后的后端服务器. 上篇:如何构建一个多人(.io) Web 游戏,第 1 ...

  9. Golang+Protobuf+PixieJS 开发 Web 多人在线射击游戏(原创翻译)

    简介 Superstellar 是一款开源的多人 Web 太空游戏,非常适合入门 Golang 游戏服务器开发. 规则很简单:摧毁移动的物体,不要被其他玩家和小行星杀死.你拥有两种资源 - 生命值(h ...

随机推荐

  1. Poj(1521),哈夫曼编码

    题目链接:http://poj.org/problem?id=1521 这里,网上有很多博客都有写,很多人没有建树,直接就是求一下这个哈夫曼编码的长度,的确很巧妙,我也用的这个方法,但是,几乎所有博客 ...

  2. 学习MyBatis之简单入门HelloWorld

    转:https://blog.csdn.net/gaomb_1990/article/details/78299784 一.准备 Eclipse:Luna Service Release 1 (4.4 ...

  3. Java小吐槽

    简单说明,所有小吐槽都基于我的.NET经验,作为Java初学者,肯定有贻笑大方之处,欢迎之处,共同学习,共同进步. 1. The public type XXXXXXXX must be define ...

  4. MAC下secureCRT无法保存密码的解决方法

    在mac下新安装了secureCRT,取代系统自带的终端工具,主要是为了方便链接服务器.mac下面的secureCRT默认保存不上密码, 我们选择了保存密码后,下次登录还是提示密码错误,需要重新认证输 ...

  5. python读取mat文件

    一.mat文件 mat数据格式是Matlab的数据存储的标准格式.在Matlab中主要使用load()函数导入一个mat文件,使用save()函数保存一个mat文件.对于文件 load('data.m ...

  6. Linux添加新硬盘,设置分区和开机自动挂载之图文教程!

    虚拟机添加硬盘的步骤就不多废话了,主要列出添加硬盘后要进行设置的几个详细步骤: 1.查看磁盘信息:fdisk -ls 添加前如下图所示: 添加后如下图: 也可以用:ls /dev/sd*查看,如下图: ...

  7. java基础必备单词讲解 day two

    variable 变量 count 统计 sum 总数 salary 薪水 Scanner 接收 import 导入 eclipse 日食 control 控制 shift 改变 alt 替换键 ha ...

  8. LOJ#515. 「LibreOJ β Round #2」贪心只能过样例(bitset)

    内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: nzhtl1477 提交提交记录统计讨论测试数据   题目描述 一共有 nnn个数,第 iii ...

  9. 7-3 python操作excel

    1.写excel 写入特定单元格数据 # .导入xlwt模块 # .新建一个excel # .添加一个sheet页 # .往指定的单元格中写入数据 # .保存excel import xlwt boo ...

  10. php-安装与配置-未完待续2

    一,准备工作 在入门指引中,我们已经知道PHP的3个应用领域,不同的场景,需要安装的东西是不同的.具体如下: 服务器端脚本,在通常情况下,需要三样东西:PHP 自身.一个 web 服务器和一个 web ...