最近刚好看到消息说《赛博朋克2077》这款游戏正式结束开发了。在通过DLC《往日之影》最终为这个游戏挽回声望并且扬长避短之后,这款游戏话题之作的官方故事就算告一段落了。
近期我更新的思路就是有什么想说的话题,就先去GDC和SIG的历史记录里翻找权威性的分享;例如想说明《赛博朋克2077》这款游戏开发的困难,这次找到的这篇UI开发分享我觉得就很有代表性——这里的UI更多的是广义上的UI,即游戏中各类平面表达和交互界面都可以认为是UI。
在看到这篇2023年的GDC Showcase上的分享后,我觉得其中最突出点是:分享者事无巨细地列举了整个UI开发中面临的各种课题,既有时间上的视角,也有阶段性的问题意识。
相比来说,这篇分享可能不是那种讲细节干货的类型,但是能让大家窥见世界上为数不多的3A项目在开发中面临的实际挑战与人们的努力。虽然可能产品上线时整体仍然还有不少BUG,不过相对于他们面对的整个巨大难题来说,实现得算很不错了。
*后面的内容还是以翻译PPT页的内容为主,对于信息不足的部分会补充一些我自己的分析。顺便一说,这家公司的PPT都做得很有精美,能看出这个项目的艺术气质;另外,由于他们母语不是英文,部分地方的英文无论是读起来还是翻译过来都会比较别扭——不过在原文基本通顺的情况下,我还是尽量保留了原文的词语内容。
*随着3A游戏的表达方式越来越丰富,UI的内容早已不局限于老老实实停在屏幕角落中的一些按钮、文字和图片了。从3D空间中的指示层UI,到融入3D物体的UI,“用户界面”的这一概念内涵的表现形式早已不局限于动态的图片与文字,特效、动态物体等都可能组成UI。这篇分享的后面也能看到UI内涵不断丰富的这一过程。
引擎内创建
更少的迭代时间
使用引擎内的子系统
更高的密度和复杂度
更多动态元素
支持多语言
在3D空间显示与交互的可行性
可包含嵌入的视频
使用自定义材质和特效的可行性
——引擎内多目标并行开发( Multi-Variable Programming ):
简单的widget类型(widget就不翻了 这个是UI系统控件的常用词语)
2D输入传播(有些引擎里用dispatch这个词,类似的意思)
排版布局构建
集成到Red引擎的系统中——渲染、输入系统、文件系统
包含完整功能的UI系统
简单的3D功能实现
无编辑器(所有布局通过C++硬编码)
支持嵌入视频
合适的实现——引擎、UI、游玩层的连接
合适的管线——编辑器和资源导入工具
合适的游戏内UI——不是通过硬编码
和更多...
*CDPR这个公司的产品是大量使用中间件的,这意味这一旦想要深入做定制化的需求,就需要从头打造一个UI系统,从设计、逻辑到工具都是零基础。从后面的时间节点也能看出,每年除了优化以外又不停引入新的特性,这个节奏持续到项目上线。
*Budge 指标,预算。Starting Point是他们当时的状态,即优化的起点(可以看出差距挺大)。
屏幕空间UI——小地图、地图图钉、3D地图、道具栏、Perks、HUD元素。
世界空间UI——武器UI、车内UI、设备系统、公告牌、本地化的街边告示牌、全局的TV系统、任意地方的本地化文字。
——UI实例:独立的UI层级结构,包含起所有依赖的资源和物体,例如纹理、动画、渲染对象,被一起实例化到内容中。产生自Widget库中的一个物体预设。
——Widget库元件。可被实例化的简单的UI层级(模板),存在于Widget资源库中。
——Widget库资源文件。定义了一组Widget库物体资源或依赖资源(的对应关系)的文件。
*Unity和UE中都有类似的结构,区分模板和实例是可编辑的UI框架的基本内容。另外几处术语定义由于他们母语不是英文,所以有些用的名词的准确性是存疑的。
4 UI实例分类——Group UI Instances
*这里的offscreen从后文来看是一套预加载层
提取所有独立的计算项,并使它们异步进行
使用独立的渲染目标来异步绘制UI
缓存一切必要的东西
一帧中尽早开始UI的执行过程
*这里可以看到CDPR在自研开发中也是从同步执行的原型到面向对象多线程逐步解耦的设计模式。任何3A项目放下中间件从零自研一个大模块,一定是想寻求独创特点的,这一点UE引擎给不了他们。
5 减少UI刷新——Reduce UI Updates
*这里censorship 审查、检查,从后文来看这个是指需要基于审查标准动态调整的控件。
基础的事件逻辑是相对轻量级的
严格控制基础逻辑的帧调度
如果可能就关闭帧调度
避免大规模的数据拉取
6 减少UI动画刷新——Reduce UI Animation Updates
全部(UI控件)可动画化的
包含视频
几乎所有文字都是需要本地化的
基于玩家的选择动画可能有分支表现
任何部分可能在任何时候被播放
——动画定义(模板):将特定的动画插值系统及事件定义,以特定顺序配置在时间轴上的元件。顺序和属性在运行时不会改变。
——动画插值系统:控制如何进行特定动画插值的信息的元件。
——动画实例:查找(对应)到动画定义和储存的插值参数,基于一些发布的播放选项来播放动画时间轴。可在运行时修改。
7 UI实例剔除——UI Instance Culling
*这部分主要介绍了关于广告物体层的处理,一般游戏开发这部分内容不会划归到UI系统中,不过由于其介于场景物体和UI物体之间,他们这么考虑也是有道理的。
距离检测
视锥体剔除:旋转、运动预测,惯性机制
遮挡剔除:定制化的软件实现
屏幕覆盖:“weapon plane”的问题。
静态纹理替换
“车内”情况:延后流式加载,跳过刷新或绘制
*由于没有讲解原文的文案,这里实在不明白“weapon plane”是个啥问题。一般提到屏幕覆盖大致就是基于其占屏尺寸比例来进行刷新率、精度等各种维度的质量调整,但这里不确定是不是这个意思。
相对于普通3D几何体,使用优化后的管线
如果UI实例不可见,则设置为未激活状态
基于UI实例占的屏幕比例调整渲染质量
*我能理解他们不把广告牌作为环境物体而是UI的原因是其行为模式更接近他们定义的UI。What ever...
8 延迟刷新与绘制——Deffered Update & Draw
*这里不是延迟渲染管线的那个延迟,而是指时间上的延后(其本来的意思)。基本上说的是 一套预加载机制,但是用的词语都比较绕。
5个全局的TV频道,每个包含3个绘制pass
车内过多UI实例
巨量的图标
*从左到右分别是:UI模板控件、预渲染的视频、UI叠加层,它们共同构成了一个简单的电视频道显示。
*这部分其实看图看不出,但是用性能较低的设备玩过这游戏的应该更有体会。
9 3D空间中UI的HLOD——HLOD for UI in 3D-World
*这一节用路牌系统的渲染讲了类似Mipmap的机制,只不过他们做成了一套LOD系统。
类似广告牌
需要本地化,但不是随机的
在运行时进行集成
在夜之城有成百上千这样的路牌
渲染目标快速的片元着色
截止时间和指标预算是你的朋友(高情商环节)
代码解耦和并行执行是非常重要的解决方案
你需要有一个惊人的团队来做惊人的事(高情商环节)
最初包含3个开发人员
最终包含了3个UI组(艺术、设计、编程)
UI编程人员的峰值:11个
*下面的感谢与特殊感谢就不翻了。最终这套UI系统虽然也在性能较低的设备上由于异步加载策略之类会有一些Bug,但比起游戏主循环的Bug来说症状还是轻很多了。
读了这篇分享我最大的感受是,他们对UI系统的拆分和理解和其它主流的商业引擎有着一定程度上的不同,这其中既有其优势也有其实现别扭的很多地方。但无论如何,分享人提出的这些课题是真切存在的,也正是这些内容极大地丰富了《赛博朋克2077》这款游戏的视觉表现。
如果有一定开发经验的读者可能会感觉,他们总结的take away都是很基础的思考,但是实现到这个巨型3A项目中还是非常困难的。一方面他们在工业化管线的设计上确实不如那些商业引擎公司,但另一方面他们也确实能开发出完全符合内部需求的UI模块。
这里可以Callback到持续会被讨论的“是用自研引擎还是用UE之类商业引擎”这个辩论上来。显然作为一个前作大量使用中间件搭起来的开发团队,这一作他们付出巨大努力搭建自己的UI系统,又何尝不是一种还技术债的过程呢;如果使用UE,或许这里面大部分的事项他们可以更高效的完成,但可能其中很少的一部分特性就几乎无法实现。
或许得益于人力成本上的优势,或许是这个产品作为光追展示最强游戏的地位,又或许是DLC《往日之影》赢回的极大声誉,总之得益于最终还不错的商业成绩,这群思路清奇的波兰人在这款游戏中完成了他们RedEngine的极大进化,应该可以在下个项目轻装上阵、有备而战了。
评论区
共 2 条评论热门最新