图形引擎实战:3D体素场景技术分享

大家好我是来自畅游引擎部的考拉,转眼间作为校招生来到畅游引擎部也有快两年的时间了,今天就用最近一直在维护的3D体素项目来介绍一下引擎部的日常工作内容。

引擎部的工作大致上就是进行技术预研,然后将预研出的技术封装为中间件推荐给项目组使用,在接入项目的过程中根据项目组的需求对中间件做一些针对性地修改,然后支持项目完成接入并负责后续的功能维护。

一、项目介绍

先来大概介绍一下3D体素项目,3D体素项目基于Unity可以将正常的unity场景体素化,将其抽象为类似《我的世界》一样的场景模式,相比于mesh数据体素数据更加规则,有更加高效的空间查询效率,在此基础上可以较为便捷地实现行走轻功、寻路等逻辑。并且考虑到客户端与服务器的同步问题,较为离散的体素数据同步成本较低,并且不易出现浮点数等引起的数据精度问题。此外还可以实现自由添加、复制旋转移动的体素积木功能,还支持根据积木的摆放实时修改寻路数据。以上功能可以基本上满足一个mmo游戏的需求。

体素化前

体素化后

二、行走优化

这里用具体的案例来说明一下我们的工作流程,在3D体素基础构建完成后我们决定在其中新增行走的逻辑:第一步是实现功能,这一步是脱离项目方的,首先要根据自己的理解对功能做一个初步的实现,因为体素场景数据离散的特殊性,在体素场景中实现行走逻辑需要考虑到很多细节问题,比如说如何实现碰到墙壁后贴墙行走,如何将行走的逻辑与寻路相结合,如何确定在地面上站立的高度,在充分地思考和不断调试后,我初步实现了一个体素场景中的行走demo。

抖动视频(视频见链接:https://zhuanlan.zhihu.com/p/536429968

但是当我将demo提交给项目方时,他们从用户实际游玩的角度提出了一些意见和看法,比如说因为行走时所用的高度信息是来源于体素的,当人物的位置从一个体素跨越到另一个体素上时会产生高度的突变,导致行走的时候会产生抖动的感觉,但是这种抖动会给玩家带来很糟糕的游戏体验,再包括本来在体素世界的设定里不可行走的体素是不能站立的,但是从游戏表现的角度出发,在不可行走区域有一个滑落的效果才是合理的,当然我们的工作是为项目所服务的,所以要尽可能地满足项目方的需求,在收到这些改动需求后我先要对这些改动的可行性进行评估,进行技术选型,对于那些实在无法实现或者代价过于昂贵的修改,积极与项目沟通,商讨出一个折中的解决方案。

就拿解决抖动问题来说,本质上是体素的形式使数据变得离散,精度缺失,要想平滑地行走就需要原本场景mesh的真实高度,但是又不能直接通过引入mesh和unity射线来解决问题,这与我们使用体素的初衷相违背,最后又经过一番苦思冥想后,我通过在体素数据中记录体素高度与真实高度的偏移量,再结合二次插值,通过每个体素单位仅增加一个字节的内存开销的方式成功解决了行走时的抖动问题

优化后视频(视频见链接:https://zhuanlan.zhihu.com/p/536429968

三、射线优化

射线在体素场景中的应用十分广泛,包括上文提到的行走功能就是基于射线实现的,在实际的游戏中,可能有许多角色需要在客户端同时计算行走逻辑,这就要求我们尽可能地提高射线的性能。

在体素场景中,体素的高度信息按照XOZ平面划分的id来进行存储,在进行射线检测时,要先将射线投射到XOZ平面上,获取射线覆盖到的id,再对每个id上的体素相交情况进行判断。

普通情况下

如上图所示,要判断射线是否与体素相交,需要依次遍历id 0 到 3的体素信息,计算在每个id上射线的相交高度范围,与体素信息作比较。

但是在一些特殊情况下射线并没有与体素相交,但是还是需要遍历所有经过的id后才知道这一信息,十分消耗性能。如上图所示,我们需要遍历所有id的体素信息才能得出射线结果。对于这种特殊情况我引入了八叉树进行判断按照空间关系构建出一份体素场景的信息。

在进行射线查询时预先在八叉树上进行查询,如果查询到当前区域没有体素信息就可以直接返回没有碰撞的结果,大幅提高了这种情况下的体素射线性能,并且明显优于unity原生射线。

八叉树体素信息查询

除此之外还有一种特殊情况下的射线可以进行类似的优化,那就是水平发射的射线,因为体素场景的高度具有一定特点,体素的上下表面高度值也是离散的,所以我们可以按照高度值对体素信息进行切片,将具体高度值的体素信息转为二维信息,在此基础上构建四叉树进行射线的跳过优化。

水平射线优化

如上图所示,如果在n---n-1的范围内发射一条水平射线,在不经过优化的情况下,要经过从0-4判断5个id的高度信息才可以确定碰撞点,但是在构建四叉树后经过查询可知当前高度id 0-2的范围内没有体素,只需从3开始判断两个id即可,通过这种方式也大幅减少了水平射线的数据查询次数。

这两种优化基本上覆盖了游戏行走逻辑会调用的射线情况,为游戏性能的提升做了保障。

三、结语

希望从上面的案例中可以大致上反映出我们的实际工作内容,总的来说在引擎部的工作让我获得了很多成长,在进行技术预研的阶段,一方面可以有较为宽松的时间来了解游戏行业中的各种先进技术,可以拓宽视野,在学习先进项目的过程中也可以让你的代码能力和思维获得快速提高;另一方面与项目的交流也是十分重要的,他们可以从实际的角度出发,告诉你什么样的技术才是现在最为实用的,才是用户所喜欢的,而且和项目合作开发的过程中也快速提高了我的工程能力。如果你也对新技术感兴趣,并且乐于钻研那么畅游引擎部一定会是个不错的选择,希望可以在这里见到你。

欢迎加入我们!

感兴趣的同学可以在官网投递简历:

内推码:NTAI1kh

全部评论

相关推荐

头像
10-09 19:35
门头沟学院 Java
洛必不可达:java的竞争激烈程度是其他任何岗位的10到20倍
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务