一、前言

随着用户对游戏品质需求的提升,MMORPG作为网络游戏中最重要的一种类型,也在潮流中不断的进化着。现在,网络游戏已经从之前的2D,2.5D时代,进化到了全3D时代。玩家可以在游戏中自由的轻功跳跃,飞行,上墙进屋,MMPRPG的玩法与体验得到了进一步的提升,更加接近于虚拟现实。

全3D时代的网游,对于网络游戏服务器提出了新的挑战。

面对新的需求与挑战,天涯明月刀项目在服务器端另辟蹊径,在提供不输于2D系统的性能的前提下,实现了一套全3D且逻辑安全的服务器端引擎。同时实现了性能,精度,安全三者的兼顾与平衡。

二、技术背景/业界现状

在客户端引擎方面,经过多年的发展,虚拟3D世界的构建已经有着较为成熟的技术。现在市场上有多款成熟的商业引擎诸如CryEngine,Havok,Gamebryo等可以借鉴与使用。

但是在服务器端,MMOPRG服务器无论是从用户模型,硬件现状,以及业务形态都与客户端有着巨大的差异:

a) 、硬件支持有限

服务器硬件少有像GPU类似的专用图形图像计算单元,只能依赖于CPU进行计算。CPU的浮点运算能力远远低于GPU

b) 、完全不同的业务模型

一般而言,MMORPG客户端需要同时精确计算的对象局限在较小的空间范围内(诸如九宫格视野范围内),数量较少,服务器必须接近实时地计算世界内的所有玩家所处的位置与状态

c) 、更多的计算需求

在单个svr进程上需要支持3-4k玩家同时进行游戏;

目前业界中,服务器端的3D解决方案有如下几种:

1) 、多边形网格(Polygon Mesh)

图1:基于Polygon Mesh的3D场景描述

将客户端的引擎移植到服务器端

优点

精度高:可以做到与客户端相同的精度表示

缺点

计算量大:碰撞计算非常消耗CPU

资源量大:需要在服务器端导入大量的美术资源

开发难度大:要讲通常跑在客户端的引擎代码移植到服务器端,迁移成本较高

结论:

l        性能上无法满足MMORPG大世界的承载需求

l        可以通过增加机器的方式对性能需求做出一定的缓解,但是会拉高整体的运营成本

l        通过降低精度可以缓解计算压力,但是精度不再的话就丧失了唯一的优势

2) 多层网格(Layer Gird)

图2:基于 Grid Layer的3D场景描述

通过添加多层扩展传统的服务器2D网格场景描述

 优点

计算量小:无需计算复杂的碰撞,只需检查网格碰撞即可

开发难度小:大部分的2D行走逻辑可以继承,只需要在切层时做额外处理

 缺点

资源生成困难,描述能力不足:

复杂建筑用层来分割非常困难,数据生成难度很大。

如下图:

上图中循环上升的回廊,回廊在不同高度上究竟属于那一层?

重叠的部分理论上应当属于不同的层,但是按照多层网格数据格式的定义,又应该属于同层。在描述上会出现矛盾的尴尬境地。

上面的例子很实际的说明了多层网格的描述能力是有限的,而且遇到复杂建筑的时候,如何正确的描述建筑规格,会遇到很大的困难。Case by Case的解决也无法完全消除问题,而且效率很低。

精度较低:由于采用固定规格的格子大小,在描述一些形状较小的复杂物件的时候会存在精度问题。

结论:

l        性能上可以满足承载需求

l        数据制作难度过大,且存在描述能力不足的问题,无法满足内容制作需求

三、设计方案

3.1、Voxel概念的引入

Voxel即体素(Volum Pixel)的简称。Voxel体素的概念是从二维空间的最小单位像素衍伸而来。像素用于描述二维的影像,是二维空间上的最小单位。而体素则可以用于描述三维空间上的立体的对象,是三维空间分割上的最小单位。

图3: Pixel 描述的二维图像

图:4:Polygon Mesh描述的三维对象

图5: Voxel描述的三维对象

Voxel描述相较于Polygon Mesh的优势在于:

性能

Voxel本身是规格化的,无需使用浮点数运算,避免了服务器CPU浮点运算能力的瓶颈。

通过合理设置精度范围(Voxel的大小),可以大大降低服务器的计算频率,减小计算压力,同时保持比较好的C/S同步。

资源

相比Polygon Mesh,资源描述简单,服务器使用规格化的数组即可描述,加载,解析,存储都很方便。

开发难度

Voxel本身就是在2D基础上的概念扩展,从2D系统迁移到Voxel系统的过程中,迁移成本较低。且其中原有3D系统阻挡Mask的概念还可继续沿用。

如何用Voxel来描述复杂场景,让我们在下一节详细展开。

3.2、 基于Voxel的3D场景描述

使用Voxel对场景进程3D描述的具体方案如下:

l          将3D场景以Voxel为单位进行离散化描述

l          以 (x, y, layer) 三元组对场景描述voxel的位置进行定位

l          以 (x, y, z, layer) 四元组描述移动对象在空间的位置

l        (layer为冗余量,用于快速定位同一垂直投影上的Voxel对象)

l          layer = 0 的voxel为地表层,voxel记录上沿(upward)高度

l          layer > 0 的voxel为建筑层,voxel记录上沿(upward)与下沿(downward)高度

图6:室内室外场景Voxel描述剖面图

图7:拱桥Voxel描述侧视图

上面的Voxel示意图中,绿色的Voxel为0层,黄色的为1层,蓝色的为2层。

可以看到,视觉上处于同层的蓝色与黄色,实际上是处于不同的逻辑层上的。也就是说,在Voxel方案下,层的概念只在水平grid的垂直投影面上才有意义。相邻的Voxel之间,层id相同,并不表示联通/或相接,因此,原有的行走检测算法已经不再适用,需要引入基于Voxel的碰撞检测算法

图8:天涯明月刀场景常规视图

图9:天涯明月刀刀场景Voxel视图

3.3、基于Voxel的碰撞校验算法

通过对玩家在游戏世界中的移动行为进行研究,我们可以划分并得到两种行为模式:行走与轻功。

3.3.1、行走

玩家在行走时,脚步不会离开地面。用voxel的视图来表述的话,玩家的移动就是在不同voxel之间切换,且玩家的高度(z轴坐标)始终是当前所在Voxel的上沿的位置。

既然玩家的高度是由所在Voxel确定的,那玩家在行走的过程中,其实是不用处理高度信息的,以(x, y, layer)三元组即可描述/处理玩家的移动路径。

3.3.2、轻功

轻功过程中,玩家的脚步脱离了地面,即玩家的移动不再限制于Voxel的上沿表面。此时,需要(x, y, z, layer)四元组来描述/处理玩家的移动路径。

通过对于移动模式的分解,我们可以进一步细分碰撞模型:

3.3.3、行走 

行走的碰撞校验步骤为:

1、  Grid Mask判定

Ø  检测Voxel对应的Grid Mask

Ø  静态阻挡、动态阻挡、水面阻挡等

2、  高差判定

Ø  相邻Voxel的高度差是否在合理范围内

Ø  高差判定的方向性:

Ø  从高处可以往地处走无需考虑高差

Ø  从低处往高处走,需要考虑高差,太高走不上去

3、  碰撞判定:

目标Voxel之上的高度空间是否能容纳移动对象

经过这三步,就可以完整的判定移动是否合法。下面是流程示意图:

图10:行走逻辑碰撞判定规则

3.3.5、轻功

轻功的碰撞检测步骤为:

1、  Grid Mask判定

Ø  检测Voxel对应的Grid Mask

Ø  空气墙,动态阻挡

2、  碰撞判定

Ø  目标Voxel上的空间是否可以容纳移动对象

Ø  移动路径前方是否有Voxel阻挡

图11:飞行逻辑碰撞判定规则

图12:碰撞判定示意图

3.4、服务器端3D引擎构架

通过封装3D场景管理数据读取以及碰撞算法,天涯明月刀server形成了一套完整的以voxel描述数据为核心的服务器端3D引擎构架。

示意图如下:

图13:服务器端3D引擎构架示意图

3D场景引擎:

Ø  数据管理模块位于最底层,提供了基础的地形碰撞信息读取接口。

Ø  在底层Voxel数据管理的基础上,实现了多层Layer的管理。

Ø  Voxel数据与Layer Patch(详见下文)数据统一放置到场景数据管理器之下。

Ø  碰撞校验API以及场景数据API访问场景数据,并向上层提供服务。

Ø  同时提供一套运动计算引擎,封装了常规的运动计算公式的实现,可以供上层移动逻辑调用。

移动控制模块:

Ø  提供行走,轻功,拖拽等多种方式的移动模型,可以充分满足业务逻辑的开发。

业务逻辑:

Ø  AI,玩家移动以及技能位移作为最上层的逻辑,直接调用移动控制模块提供的接口即可,无需关心底层实现,简化了一线业务开发的工作量。

四、性能优化

在之前的技术方案评估中,已经论证了Voxel方案比起Polygon Mesh方案有着较大的性能优势,但是相较于之前的2D移动方案,性能还是有大幅度的下降。

为了实现单进程3-4k玩家数的承载的目标,从用户模型与数据特性出发,我们对Voxel方案进行了细致的优化,最终实现了和2D移动方案下相近的性能。

4.1、时间优化

4.1.1、多层索引Cache(Layer Mask Cache)

图14:多层索引示意图

要点

碰撞检测算法中存在大量指定(x,y),获取此grid垂直投影面上所有层信息的操作。经过统计此处操作函数为热点函数,且占用了大量的cpu时间。

针对这个问题,可以通过预先生成并缓存layer mask,在运行时访问layer mask缓存,即可快速定位并获取grid垂直投影面上层的信息

副作用:

内存消耗增加,地图大小为4km x 4km,且每个voxel平面大小为50*50的情况下,需要额外占用64M的内存

4*1024*100 / 50  = 8192;  // 地图以voxel为单位的边长

8192 * 8192 = 64M        // 整体内存占用

与不优化的情况相比,单张地图资源内存使用增长了15%左右,从整体性能trade off来看,还是划算的。

4.1.2、连通性Cache(Connectivity Cache)

图15:连通性cache示意图

要点

为了美术数据制作限制,导致出现穿墙等行为,在3D引擎内部,移动对象的连通性判断限制为在相邻grid之间的四方向之间进行。外部传入的路径会经过转换生成一条在四方向之间进行移动的路径。

通过仔细分析我们可以发现,相邻grid之间,同一个方向上,从src层只能切换到一个唯一的dst层,即相邻grid之间的连通性是唯一的。

由上面的分析可以看到,决定连通性条件都是静态的,在运行时进行碰撞检测来计算连通性,实际上存在大量的重复计算。

同时,经过统计,90%以上的地表只有0,1两层,我们只需要对这两层的碰撞判断做针对性的优化,即可覆盖绝大部分的计算。

综上,我们提出了一套基于联通性Cache的优化方案:通过预先计算碰撞信息,生成全图的连通性Cache,在运行时直接访问Cache获取连通性信息,避免重复计算,可以极大提升运行性能

优化效果

Ø  相邻Grid连通性碰撞检测平均时间消耗从2000 CPU周期降低至200

Ø  场景服务器整体CPU消耗降低30% (单进程3000人在线战斗 + 移动)

副作用

内存消耗增加,4km x 4km 的地图需要额外占用128M的内存。

与不优化的情况相比,内存使用增长了30%左右,虽然在时间优化方面有了非常大的提升,但是将压力转移到了内存空间使用上,下面我们会针对这种情况做进一步的空间优化。

4.2、空间优化

天涯明月刀刀的地图大小是同类游戏中最大的(4km x 4km),按照之前定义的Voxel模型,我们可以推算一下,每张大地图的内存使用量:

Ø  大地图面积:8192 * 8192(4 km)

Ø  Mask+上下沿高度: 5 byte

Ø  全图最高建筑层数:8

Ø  场景地图数:8

Ø  单张地图所需内存:2.5G

所有地图需要内存:2.5 * 8 = 20 G !

除此之外,还需要加入之前因为时间优化需求而加入的各种cache数据,对内存的需求会进一步膨胀,这显然是无法接受的。为此我们必须要展开内存使用优化。

4.2.1、多层补丁(layer patch)

首先我们观察到,地图大部分都是野外(0层, 90%),只有城市中才存在多层建筑。这种情况下,0层以上大部分的数据都是空的,没有这部分内存被完全浪费掉了。

基于这样的数据特性,我们提出了多层补丁(Layer patch)的数据组织方案,来实内存优化。

多层补丁,即为0层以上的地形,不已全图的形式展开,而是以补丁的形式存在,有数据的地方才有补丁。诸如下图:

图16: Layer Patch示意图

layer 1可以简化为两个patch,layer 2可以简化为1个patch,数据量大大降低,从而节省了更多的内存。

优化后:

Ø  0 层: 8192 * 8192 * 3 = 192M

Ø  2 个patch层,每层有100个patch,每个patch大小是 50m * 50m

Ø  100*100*5*100*2  = 10M

Ø

单张地图所需内存  200+M

通过layer patch的优化,显著降低了内存使用量,使得方案达到了可用的程度。

4.2.2、多进程地图资源共享

在天涯明月刀超大地图的设定下,经过patch优化后,单场景服务器内存使用依然达到16G(其中地图6G)。如此一来,B6机器只能支持部署3个场景服务器(scened),而B6机器上有12个计算核心,多核计算资源被大量浪费。

然而仔细分析,我们的多个scened进程其实都是是同构的,其中的地图数据也是相同的,且这部分数据都是只读的资源数据。在同一台物理机上的多个scened各自都加载了一份庞大的地图数据,如果能把这部分数据做成共享的,那我们将节省出大量的内存资源。

在这样的情况下,我们提出了一套多进程资源数据共享的方案:

图17:多进程内存共享示意图

优化方案:

Ø  将资源数据从单个场景各自加载改为统一加载至共享内存中

Ø  各个场景服务器attach至共享内存,使用同一份数据

优化后:

Ø  单机整体内存占用下降30%(3 scene 部署情况下)

Ø  5 scened机部署可以改为单机部署

4.2.3、开发模式地图资源按需加载

天涯明月刀团队有着140人的规模,针对大项目组多人协作的情况,我们设计了一套完整的服务器私服部署/版本分发体系,力求项目组中的每个人都可以拥有一个自己可以控制,调配的私服,实现无干扰的高效开发。

但是我们的场景进程在dev模式下内存需求达到14G,导致B6机器只能支持部署3组私服,140人规模团队,私服需求巨大。目前我们有12 台vb4,6 台A5,2 台B6作为私服,但是还是无法有效满足团队需求,内存紧张一直困扰着我们。

针对这种情况,我们针对dev模式设计了一套地图数据按需加载模式。

地图数据按需加载,dev模式启动时只加载一张默认地图。采用先全量加载,再释放冗余地图的策略,保证资源校验的完整性。然后在发生传送/进入新地图事件时,按需动态加载地图数据。

优化结果:

Ø  单scene内存需求下降至8G

Ø  以20台左右服务器支撑起100余套私服

Ø  有效支持全项目组的日常开发工作

Ø  解决以后新增地图情况下私服内存紧张问题

Ø  为公司节省大量dev-net机器资源

4.2.3、性能基线

最终的优化完成之后,我们实现了单个进程支撑3000人同时移动下场景服务器压力维持在20%以下的目标。

图18:服务器移动性能基线表

五、结语&挑战

通过这套服务器端3D引擎,有效支持了天涯明月刀的玩法与功能特性开发。且为工作室日后的新项目提供了开发与借鉴的基础。

但是不足之处还有很多,在未来的日子里,sever组会进一步强化引擎的功能,以在玩法开发方面提供更多的支持。

未来可能会考虑引入可变精度的Voxel来实现更高精度的场景需求;同时也会实现动态建筑建造与升级等功能,还请大家拭目以待!

《天涯明月刀》服务器端3D引擎设计与开发相关推荐

  1. NVIDIA强强联手 《天涯明月刀》3D引擎解密

    在不久前的腾讯游戏2013年度发布会上,<天涯明月刀>刚刚以一首藏头诗的方式提示4月22日的惊喜揭秘.4月19日,腾讯游戏就在首映礼上宣布这款电影网游即将进入首测阶段,与四位好莱坞级电影人 ...

  2. 3D引擎架构设计篇-姜雪伟-专题视频课程

    3D引擎架构设计篇-169人已学习 课程介绍         本课程是针对3D引擎架构设计,涵盖引擎的基础模块,多线程基础框架,大场景加载,地形多纹理优化技术,GPU优化渲染,物理引擎,AI算法以及A ...

  3. 2021-2027全球及中国3D网页设计服务行业研究及十四五规划分析报告

    2021-2027全球及中国3D网页设计服务行业研究及十四五规划分析报告 2019年,全球3D网页设计服务市场规模达到了xx亿元,预计2026年将达到xx亿元,年复合增长率(CAGR)为xx%.中国市 ...

  4. Unity 中国区总经理符国新:3D引擎开发

    [提要]  由成都市人民政府.移动游戏发展联盟.中国移动通信联合会主办,人民网.腾讯网.当乐网共同协办的"2012移动游戏大会"12月20日在成都川投国际酒店隆重举行.Unity ...

  5. 3D引擎架构设计高级篇

    3D引擎架构设计最核心的技术包括:引擎框架设计,引擎内存管理,大场景加载以及卸载,引擎的渲染,模型骨骼插件:其他的模块还有粒子,AI,行为树,UI等等吧. 市场上对于引擎开发的需求也是比较大的,而且薪 ...

  6. android+3d引擎,基于Android系统3D引擎的设计与实现

    摘要: 随着人们生活水平的提高与科学技术的高速发展,在嵌入式设备上开发3D应用程序将会成为亮点,把3D技术应用到Android产品中,会极大的提高产品的竞争力.而3D图形开发的过程中所涉及的知识相当广 ...

  7. qt5.9.0调试如何查看变量的值_从0开发3D引擎(四):搭建测试环境

    大家好,本文介绍了3D引擎的测试方法,搭建了本地的测试环境. 上一篇博文 wonder-yyc:从0开发3D引擎(三):搭建开发环境​zhuanlan.zhihu.com 下一篇博文 wonder-y ...

  8. 用函数式编程,从0开发3D引擎和编辑器(三):初步需求分析

    大家好,本文介绍了Wonder的高层需求和本系列对应的具体功能点. 确定Wonder高层需求 业务目标 Wonder是web端3D开发的解决方案,包括引擎.编辑器,致力于打造开放.分享.互助的生态. ...

  9. 3D游戏引擎设计 实时计算机图形学的应用方法 第2版 pdf 带索引书签目录

    3D游戏引擎设计  实时计算机图形学的应用方法  第2版 目录 第1章 概述 1.1 图形硬件和游戏发展史 1.2 本书版本与软件发展史 1.3 章节导读 第2章 图形系统 2.1 基础知识 2.1. ...

  10. Android 3D 魔方游戏的设计与开发

    Android 3D 魔方游戏的设计与开发 5.1 Feature 定义 魔方是一个有趣的益智游戏,相信很多人都玩过.本次毕业设计,欲完成的主要的功能如下: (1) 开始游戏:开始一个新的游戏 (2) ...

最新文章

  1. 万字长文揭穿你,根本就不懂云原生!
  2. 【c语言】蓝桥杯算法训练 完数
  3. IOS进阶之WKWebView
  4. linux 内核 死锁 检查,一种linux内核自旋锁死锁检测报告系统和方法与流程
  5. 103. Leetcode 213. 打家劫舍 II (动态规划-打家劫舍)
  6. colab把数据放在content下面以及放在drive下面的训练速度比较
  7. 【MFC系列-第18天】企业信息管理软件开发
  8. div水平垂直居中的六种方法
  9. activemq中怎么知道推送消息是否成功_ActiveMQ安装试用示列
  10. CentOS 6 下升级安装Mysql 5.5 完整步骤
  11. linux+html5+开发工具,记不住 Linux 命令?这三个工具可以帮你
  12. UVA12043 Divisors【欧拉筛法】
  13. Android ViewPager滑动背景渐变
  14. 程序设计导引及在线实践之时区间时间的转换
  15. mac touchbar 自定义
  16. 使用jsp实现成语接龙
  17. windows 7 旗舰版下,安装vs2010旗舰版终于成功!
  18. Unreal Engine4人物模板编辑与解析(1)
  19. Android Studio学习#2
  20. 1688图片批量采集技巧

热门文章

  1. 神秘诡异的量子世界是如何毁掉科学家三观的?
  2. Centos 7 安装 TEMPO2
  3. 格雷码-数字设计应用
  4. Excel多列数据的连接
  5. 谨防打黑工丨被“偷走”的实习期
  6. java做 binggo,CONTRIBUTING.md
  7. 中医针灸学综合练习题库【2】
  8. 在横道图中如何实现多级项目计划管控
  9. Unity ASE点光源不显示的问题
  10. 史上最酷的java音乐播放器,swing编写,炫酷界面