《超凡蜘蛛侠2》这游戏我虽然没玩过,不过在大楼之间摆荡的画面确实很深入人心——在各个角度来说这个系列都是第一方3A游戏的优等生。
这次粗读的分享来自Scott Kircher,是Insomniac的核心开发工程师和图形工程师。
这篇GDC分享吸引我的原因,除了精致的PPT外,还有就是这篇分享的干货密度之高。另一个次要的原因就是这游戏的规模之大,LOD资源无法由美术人员进行手动调整,因此逼迫了工程师尽全力想出一些办法来批量和动态优化建筑网格,最终得出了不错的结果。
*由于资料没有解说稿只有PPT页,因此还是以翻译PPT页内容为主,补充一些我个人的说明。补充说明的内容会标星号。
许多小的建筑块(tiles——瓦片形式拼接的)
这个例子中包含了2057个独立的实例
并置的——块与块之间没有连接
*关于BVH是一种空间加速结构,之前有文章介绍过。 每个建筑最大65535个顶点(2的16次方)
适配已有的游戏系统并节省内存
尽量不要重构很多不熟悉的代码
*整体来说,就是在工期有限、性能空间有限的情况下,需要把一层LOD想方设法调整成2层LOD,以提升画质并为光线追踪提供BVH数据。
减少网格工具对于较高密度LOD工作良好
重构网格工具对于低密度LOD工作良好
两者之间如何呢?
——第一级远距离城市BVH LOD(中等质量和密度的)
对过分保守的目标物重构网格
然后(把网格)减少到需要的密度
建筑数据结构“不可修改”
16位
4字节顶点
尽量减少法线贴图的使用
——通过Simplygon的减少网格和重构网格工具是不够的
缺少法线信息
(被错误)网格重构的“内壳”
网格减少导致破皮、裂开问题
——顶点格式中仅包含位置(坐标)数据,没有法线数据
——法线是在运行时、逐三角面计算的(像旧的flat-shading一样)
本来平整的结构会不再平整
看起来有镶嵌感
“三角定位故障”
*很多都是自动减面工具的一些常规问题,这类工具很难理想地处理结构稍微复杂的网格体。
通常都是未封闭的
包含一些并非实际开放的边界
一些建筑块包含背面结构
*这一段很细致的介绍了建筑这种看起来方方正正的网格结构体在使用自动化减面工具时遇到的各种问题。由于前面也介绍过,自动化处理的方案是必须执行的,所以后续他们对自动化处理后的网格需要逐一解决这些问题——这也是这篇分享干货的开始。
表面的“形”
顶点的位置
可通过(顶点的)插值计算三角面上的位置
在连续的变形中表面具备的不变性
例如:一个表面有多少个洞
可以仅通过连接性(不通过几何结构)进行推导
流形边缘——严格由两个面共享一条边
流形网格——所有边缘都是严格由两个面共享的
*配图中展示了流形和非流形的区别。Manifold一词更多表示“具有多样性的”,简化成专有名词后确实丢失了很多信息。
并非所有洞都是由形体边缘产生
用来度量拓扑结构的“复杂度”
其中V代表顶点数,E代表边数,F代表面数。对于与球面同胚的多面体,欧拉示性数恒等于2。然而,并不是所有物体的欧拉示性数都为2,例如环面的欧拉示性数为0。
此外,欧拉示性数还可以通过公式2-2g来计算,其中g指的是闭可定向曲面的亏格数(即有多少个洞)。这个公式揭示了欧拉示性数与亏格数之间的关系。(上面则是一个反算过程)
分段线性
各处有很多零(或无限)的曲率
表面的基础曲率可以作为网格的近似
有很多备选方案
*关于离散曲率是一个复杂课题,离散分段法只是一种基础的方式,更多推导方式我也没有能力全面介绍。文末会附一篇资料链接。
*这里介绍的这些数学工具主要就是用来解决之前提到的3+1个问题的。
将有相似法线的面集群化
对每个集群计算目标平面
将(平面位置和法线信息)分派到共享的顶点上——每个顶点满足最多三个(线性独立)的平面
计算满足所有新平面的顶点位置
每个“双重顶点”(或节点)对应一个三角面
每一个“双重边”对应一对连接的面
可以遍历图来查询面之间相连的区域
——在实际应用中,我们采用了边面连接图(作为数据结构)。
A. 选择下一个集群的种子面——(区域中)最大的为划入集群的面。
广度优先遍历
不访问和种子法线差距“太大”的面
这组访问到的面的集合构成了新集群
顶点可能被多个面共享
多个集群平面可能影响同一个顶点
顶点处的合并集群是集合平行的
取消(顶点处)与大的集群不平行的小集群
取消(顶点处)大于3的小集群
集群的大小用内含的面的个数来计算
2)双平面——计算平面的相交线;找到顶点位置到线上最近的点(投影到线);移动顶点到那个最近的点
计算任意两平面的相交线
计算线与第三平面的交点
把顶点移到该点位置
生成一组相连的内部面的单一集合
(以及一组外部面的集合)
对基本的方向(可以理解成轴向的)发出射线——地面方向除外。
如果向上的射线和至少3根水平射线命中了网格,则点是内部点。
命中位置与起点距离必须大于距离阈值
这可以避免检测出小的壁凹
所有初始点都在一个平面内
在地面上方一小段距离
目的是减少采样空间的“体积”
需要将其不视为射线检测的目标
这样可以避免射线的“浪费”
3)通过从命中点(或附近)射出额外的向上射线来检测“房顶”
仍可能有部分射线命中外壳
可能漏掉一些内壳的面
不过,更好的初始分类就更接近正确的结果
保留最大的外壳面集合——将其它的标注为内壳
重复处理内壳面——找到内壳面的连续集
保留最大的内壳面集合——将其它的标记为外壳。
现在我们找到了一个单一的连续内壳
内壳区域必须“接近”50%总区域范围
可以有比较松散的容差空间(40-60%)
*通过移除之前工具生成的“内壳”,可以减少大量不可视网格的渲染计算,最终提升性能。
*backstop有很多不贴合这种情况的翻译,支撑物只是相对合适的一个。
2)移除重构结果的外壳——我们把余下的部分称为支撑物
3)将支撑物(内壳或重构后的网格)添加到网格重构后的结果中
翻转绕序
视觉上堵住LOD的裂开或洞
结果并不是天衣无缝的
仅用于远距离LOD(成千上万的顶点)
支撑物通常在100-500顶点
整体约增加了1%
城市中并非所有建筑都是大楼
支撑物不适合某些物体——有其是桥和类似的辅助结构
大楼建筑应该有更大的表面区域
雕像或其它物体有更小的表面区域
直觉:原始网格表面的法线和表面的曲率相关
曲率和表面切线所在圆的半径反相关
考虑面上的一条边(如图)
*图中是一些向量计算,包括后面整个方案基本也是向量级别的计算。
对每个三角面,计算曲率和视觉重要程度
遍历网格,找到符合曲率范围的面集群
计算每个集群的额外属性和最终重要性
找到最重要的集群——如果最终重要度大于阈值,则分配法线贴图
(基于)三角面积
低估朝下的三角面
低估大楼上较低部分的三角面
低估建筑块背面的三角面
低曲率的面通常很“平”
高曲率的面通常很“细致”(意味着也不需要法线贴图)
仅关注适当曲率的面——我们的范围[1/128,4](单位:米)
遍历网格创建集群——仅跨越角落法线是可连续的边(如图)
——如果重要度大于阈值,则为其生成法线贴图——图中的建筑经过自动探测,得出需要一个法线贴图的结论
后面还有两节是自动化构建和运行时整合的概述,以及性能总结,由于篇幅原因这里略去了。有兴趣的可以直接去资料链接的原文看看。
这篇分享最吸引我的地方在于,在3A项目浩瀚的美术资产库中,敢于和最终做到了以实现视觉提升为目的开发的一整套工具体系——3D项目的优化从来不仅限于运行时,很多时候都是从美术资产的加工就开始了。可以想象,这么大规模的城市,如果不经过自动化而是以人工来加工,这是不可能完成的任务。
或许从玩家“纯玩”的角度来说,这些都对玩不提供任何加成。但视觉体验又从来不是一个可妙手偶得的过程,而是需要一个团队一起踏踏实实积累和研发的。
反过来说,这个项目中其实他们也只有一次试错机会,如果方案失败了那么画面就无法升级,或者有视觉错误,或者性能表现堪忧。实际上也不是所有3A项目都能优化成功,很多确实是以优化失败的状态上线了,这也是3A项目越来越大的一项风险——只有这种规模的项目能提供优化经验,但一旦失败可能项目就没了。
评论区
共 5 条评论热门最新