游戏专辑一 3D游戏碰撞之体素内存、效率优化(未完待续10/14)

本篇文章是腾讯游戏开发精粹的读书总结

一、背景介绍

  • 定义

体素定义:3D空间的最小表示单位

  • 主流做法

目前主要采用Bounding Volume Hierachy(层次包围盒),但这种基于Tree的检索效率并不是太高,尤其是对后台压力大。(前端只需要加载当前存在的单个地图,后台需要加载所有场景体素)

  • 查找场景复杂度

由于自管理内存,所以查找某个位置的所有体素,时间复杂度位O(1)

  • 3D游戏的三种做法
1)体素:在腾讯最先由天涯明月刀提出
2)多边形网络:缺点是查找效率较低,后台性能压力大
3)分层:缺点是地面以上很难划分层的界线,而且复杂的建筑层太多,内存太大
  • 本文适用性

本文介绍的内存优化、效率优化所使用的场景大小为长800M,宽800M,高400M

二、体素生成

1)受开源项目Recast Navigation的启发,该项目由Mesh经过体素化、地区生成、轮廓生成、多边形网格生成、高度细节生成等步骤生成NavMesh
2)因此将Recast Navigation对Mesh体素化的代码抽出来即可生成体素

三、体素内存优化

1)体素合并的原理

(1) 体素都是一个长方体,表示有实物占据了该长方体
(2)可以将Mesh只覆盖体素的表面,而生成的体素是空心,这样就可以把体素大小从36MB降低到31MB(所有的玩家进不去的空间都要做成空心的、封闭的,这样对美术的要求就高点)
(3)

2)体素合并的算法

  • 思想:

选择一个种子点,通过种子点的前后左右四个方向扩散,无法扩散的空间即为不联通的,直接的方法是构造三维矩阵,然后三维矩阵离用广度优先遍历(深度优先遍历栈一定会溢出)
(备注:这里体素长款分为0.5,三维矩阵大小为1600X1600X4000),内存占用10GB,宽度搜索一次需要20min完成。(本章的搜索方法,在1s内完成)

  • 做法(这里就简单写了,因为也没代码)
1)首先,构建原体素的反体素,反体素表示没有被实物占据的空间
2)其次,标记联通去,在antiSpans中采用宽带优先搜索,首先在队列中放入一个可行走区上放的反体素,从该反体素开始标记整个场景的联通反体素
3)在antiSpans中删除所有flags为0的菲联同反体素,并根据antiSpans重新构建spans。通过以这种方式,合并体素的算法内存降低为10MB左右,时间在1s以内.

3)地面处理

地面的下表面高度忽略,统一认为0,体素内存从31MB降低到21MB(悬空场景,下表面高度也是0,但是需要在该高度下面1m生成1层透明的小片)

4)水的处理

1)若设置水也是体素,则需要增加一个标志位标志该元素为水,每个体素就多带一个标记,但是不需要,只有个别场景有水,所以对水不采用体素
2)最直接的做法:开辟二维矩阵,在每个(x,y)处纪录水的高度,如果场景没有水,则不开二维矩阵,但是用这种方法:会造成内存的极大浪费,因为绝大部分区域没有水。
3)因此对水采用分块存储方式,每一块大小为100X100,再开辟一个二维指针数组,数组的每个元素都为指针,如果该区域有水,则指针指向100X100二维数组;否则该指针为空。

  • 举例:

例如查找(172,567)处水的高度,则首先检查二维指针数组在(1,5)处的指针指向的100X100二维在(1,5)处的指针是否为空,若为空,则无水;如果不为空,则代表有水,继续在二维指针数组在(1,5)处的指针指向的100x100二维数组里查找(72,67的高度)。

查找时间复杂度仍为O(1)

5)范围控制

1)玩家场景由外框是全部包括,然后,外框包括内框。

2)因为玩家到不了内框外,所以内框以外不用生成体素

3)地图的前、后、左、右、上边界是内框规定的编辑,但下边界比内框边界高2m,因为内框边界以下都不生成体素。

4)但是:

Ⅰ:为了防止建筑物悬空、建筑以下被遮挡的情况,需要在内框边界以上1m位置加小片体素政党
Ⅱ:为了防止玩家落到小片上,需要地图下边界比小片略高,则因此地图下边界比内框边界高2m,内框更低。
Ⅲ:如果内框边界以下地形复杂,因为内框边界以下不生成体素,则也可节省一部分内存

6)内存自管理

  • 内存管理方案
    1)地面全部存储:地面以上分块存储,类似水的存储方式。因为地面以上体素较少,分块存储可节省大部分没有体素的区域,但是也有大量的内存浪费
    2)四叉树:查找时间复杂度为O(logn),而且需要父结点到子结点的指针
    3)在每个(x,y)new一个数组,但是存在大量的内存碎片和cache miss

补充:以上的三个问题都有各自的缺点,可以采用一维数组存储所有体素信息。。。。(这里就不详细展开了,请看书了解)

7)体素内存优化算法的结果

原始内存占用44MB-》体素合并后31MB-》地面处理21MB-》范围控制后13MB-》内存自管理后8MB

8)体素效率优化

前面使用的自管理内存,使在体素之间行走的时间复杂度近似为O(1),效率提升进10倍,每个场景的平均体素大小由9.1MB降低到6.9MB

四、NavMe生成

4.1 体素生成NavMesh

4.2 获取地面高度

4.3 后台阻挡图

4.4 前台优先级NavMesh

4.5 锯齿

五、行走、轻功、摄像机碰撞

5.1 行走

5.2 轻功

5.3 摄像机碰撞

猜你喜欢

转载自blog.csdn.net/weixin_43679037/article/details/121319585