三维场景性能优化:先诊断瓶颈,再谈面数、LOD、实例化与 Draw Call
本文讲通用机制与判断方法;具体引擎的功能名称、参数项与实际收益以官方文档和目标硬件实测为准,不针对任何单一品牌硬编参数或阈值。
演示前一天,园区孪生场景在大屏上跑得一顿一顿。技术负责人下的第一道指令是”把面数再削一半”。削完重新导入,帧率纹丝不动,第二天只能把镜头运动全关掉,靠切静态视角撑过去。
复盘才发现那个场景总面数并不高,压力在别处:几万个各自独立的小构件,每帧都要一个一个提交给显卡,忙的是 CPU,显卡大半时间在等。削面数是对着没病的器官下药——没测出瓶颈就开始优化,等于蒙。
这篇讲模型进了场景之后、运行时的渲染开销怎么管。进场景之前那轮减重是另一件事,看BIM 轻量化;引擎取舍看三维引擎怎么选;全部内容在数字孪生专题。
一帧画面是怎么被算出来的
要判断卡在哪,先得知道一帧里发生了什么。粗看是三段接力:
第一段在 CPU。 引擎决定这帧画哪些对象、按什么顺序画,逐批打包提交给图形接口。每提交一批就是一次 Draw Call(绘制调用)。
第二段在 GPU。 显卡按批次把顶点变换到屏幕上、算出每个像素的颜色。顶点多是顶点着色压力,覆盖面积大、材质复杂是像素着色压力。
第三段是数据供给。 网格和贴图要提前躺在显存里,装不下就得来回搬,而搬运极慢。
三段串在一起,整帧耗时取决于最慢的一段。所以”卡”从来不是一个原因,是三个候选。
三种卡法,症状完全不同
| 瓶颈所在 | 典型症状 | 常见诱因 | 有效手段 |
|---|---|---|---|
| GPU 顶点/像素 | 看全景时更卡、降分辨率明显变好 | 面数总量大、透明叠层多、后处理开满 | LOD、简化几何、减少透明叠加、降后处理 |
| CPU 提交批次 | 面数不高却卡、降分辨率没用、对象一多就掉 | 独立小构件成千上万、材质各不相同 | 实例化、合并、共用材质、剔除 |
| 显存不足 | 加载久、转到新区域掉帧、久跑越来越卡 | 贴图尺寸过大、数量泛滥、未压缩 | 图集、压缩格式、按需加载 |
判别不难,两招就能分清:
招一:把分辨率降一档看帧率。 明显变好,压力在像素着色这侧,属 GPU;几乎没变,基本可排除像素瓶颈,往 CPU 批次或顶点量上找。
招二:做对照实验。 把某类对象整批隐藏(全部绿化、栏杆),看帧率跳多少。跳得多元凶就在这类里;再看它是”面数大”还是”个数多”——面数大偏 GPU,个数多偏 CPU。
引擎自带的统计面板通常能读出每帧批次数、三角面数、显存占用,帧分析工具还能看出 CPU 与 GPU 谁耗时更长。优先看数,没工具再用对照实验凑。 想先对量级有概念,可用站内的三维场景性能预算估算器按构件规模和屏幕配置粗算面数、批次、贴图显存的档位,再拿实测校准。
面数与 LOD:按距离给模型分级
LOD(Level of Detail,细节层次)思路很朴素:同一个对象准备几个精度不同的版本,离得远就换粗的。 远处一栋楼只占屏幕上几十个像素,精模和粗模肉眼看不出区别,开销却差一大截。
分几级合适? 判断口径是这个对象会以多大的尺寸跨度出现。始终摆在近景的展项分级意义不大;既要俯瞰全景又要推到楼下的建筑就值得多分几级。级数不是越多越好,每级都要额外制作与存储。
切换跳变怎么办? 切换瞬间轮廓突变,观众会看到一下”抖动”(popping)。缓解有三条:切换距离往远推、落在人眼不敏感的位置;切换点前后做过渡混合;相邻两级差距别拉太大,轮廓保持一致、主要减内部细节。
两个坑: 低级别模型若只简单减面而没重新处理法线和 UV,远处会破面或贴图错乱,反而更显眼;更要紧的是——LOD 减的是 GPU 侧顶点压力,减不了批次数,一万个小构件切到最低级别仍是一万次提交,这正是很多人”上了 LOD 没提升”的原因。
Draw Call:为什么重复构件是批次大户
栏杆、路灯、行道树、面砖、幕墙分格——单个面数很低,数量却是几千上万级。它们几乎从不构成面数问题,却是批次数量的主要来源。 每个独立对象、每种材质都会切出新的提交批次。压批次两条路,代价不同。
第一条是实例化(Instancing)。 同一个网格配同一份材质、重复出现很多次,只是位置旋转缩放不同——这种情况可以只提交一次网格数据,附带一份变换矩阵列表,由 GPU 一次画完全部副本。适用条件很硬:网格必须相同、材质必须相同,只有变换和少量逐实例参数可以不同。行道树、路灯、标准栏杆段、同型号灯具都天然适配。
好处是对象仍然独立。但它不免费:逐实例属性差异越多收益越薄;而且它解决的是提交次数、不解决面数——一万棵高精度树实例化之后照样压垮 GPU,得配合 LOD 用。
第二条是合并(合批)。 把一批对象的网格焊成一个大网格、共用一份材质。压批次最直接,代价也最重:合并之后它们不再是多个对象,而是一个对象——选不中、驱动不了、没法单独隐藏。 判据只有一句:这批构件是不是永远不需要被单独选中、单独变色、单独控制。 是,才能合;设备、末端点位、要做状态联动的门窗不能合。
还有个常被忽略的角度:材质数量本身就是批次来源。 同一批构件即使合并了,挂着十几种只差颜色的材质仍会被拆成十几批。归并材质、差异用贴图表达,往往比动几何省事。
纹理与显存:另一类完全不同的问题
贴图问题的特点是不随镜头远近平滑变化,而是”够用时正常,不够时突然崩”。
尺寸。 贴图占的显存和边长的平方成正比——边长翻倍,占用四倍。定尺寸的依据是”这个表面在屏幕上最多占多少像素”,不是”素材原图有多大”。
数量与图集。 把多张小贴图拼进一张大图(图集,Atlas),既省显存碎片,也帮助材质归并、少切批次。代价是后期动一张要重新排图。
压缩格式。 通用图片格式在硬盘上很小,送进显存时通常要解开成未压缩形式;GPU 专用的压缩纹理格式则能以压缩状态直接驻留显存,占用大幅下降、采样开销更低。代价是有损,且各平台支持的格式不一致,Web 端尤其要看目标浏览器与设备的支持面。这项通常是投入产出比最高的显存优化。
Mipmap。 预生成一串逐级缩小的版本,远处自动采样小的:闪烁摩尔纹消失、采样命中率提高,代价是多占约三分之一显存。
显存爆掉的症状要认得出:初次加载特别久;镜头转到没去过的区域猛掉一下、再去就正常;久跑越来越卡甚至崩。这类症状削面数完全无效,方向是压贴图、上压缩格式、按需加载。
剔除:场景总面数和每帧渲染面数是两个数
常见误会是把”场景里一共多少面”当成性能指标。真正决定开销的是这帧实际被送去渲染的量,两者之间隔着剔除。
视锥剔除(Frustum Culling) 判断对象是否落在相机可视范围内,范围外直接不提交。最基础的一层,多数引擎默认开启,也解释了为什么场景转个方向帧率就变。
遮挡剔除(Occlusion Culling) 更进一步:在视野里但被完全挡住的对象也不画,楼里的机电、被前排挡住的后排建筑都属这类。收益取决于遮挡关系有多强——室内和密集建筑群收益极大,一马平川的广场或俯瞰视角收益很小。它也不白拿:判定本身要花 CPU,遮挡弱的场景可能得不偿失。
距离剔除最简单:超过某个距离的小对象直接不画,远处的栏杆、井盖本就只有一两个像素。
剔除的价值在于它同时省 CPU 和 GPU——不提交、不计算,所以排在优化清单最前面。
大场景:分区与流式加载
园区级、城市级场景不可能整体常驻内存。做法是按空间切块,只加载相机附近的块,远的卸载或用极简替代。粒度要和视野尺度匹配:太粗,单次加载吞吐量太大会卡;太细,块的管理与边界处理反成负担。
配套两件事:一是预加载,按相机运动方向提前把即将进入视野的块调进来,否则每次移动都伴随可见卡顿;二是分级替身,远处的块用低精度整体代替,避免”边界之外一片空白”。地理尺度的场景常配合分级瓦片式数据组织,本质是同一个思路:按需要决定加载什么、加载到什么精度。
优化的正确顺序
顺序错了,力气会白花。建议这样走:
- 先量。 拿到帧率、批次数、每帧三角面数、显存占用,最好还有 CPU 与 GPU 各自耗时。没有数就没有下一步。
- 判断瓶颈在哪侧。 降分辨率试一次、隐藏大类对象对照一次,结论落到”CPU 批次""GPU 顶点/像素""显存”之一。
- 先做收益大且改动小的。 剔除设置、距离剔除、材质归并、纹理压缩格式,改配置就见效,不动模型。
- 再做结构性的。 实例化、LOD 分级、分区加载,要改资产和场景组织,工期长但上限高。
- 最后抠细节。 后处理精简、阴影范围、透明排序,每项收益不大,用来凑最后那几帧。
- 每改一项回到第一步重测。 瓶颈会转移:批次压下去之后卡点很可能变成 GPU 面数,这时削面数才终于有用。
再补两条口径:必须在目标硬件、分辨率、屏幕数量上验,工作站上的帧率没有参考价值;帧率看稳定性不看平均值,平均六十帧但每隔几秒掉一次,观感比稳定四十帧差得多。
小结
掉帧不是一个问题,是三个:GPU 算不过来、CPU 提交批次太多、显存装不下。症状不同,药方完全不同——面数不高却掉帧多半是批次问题,削面数无效;转到新区域猛掉一下、久跑越来越卡多半是显存问题。
手段各就各位:LOD 降顶点压力但减不了批次;实例化与合并压批次,合并的代价是不可逆地失去单独选中与驱动;纹理靠尺寸、图集与压缩格式省显存;剔除同时省 CPU 和 GPU,性价比最高;大场景靠分区流式加载。
顺序上只有一条铁律:先测出瓶颈在哪,再决定动哪里,每改一项重测一次,因为瓶颈会转移;验收认目标硬件上的稳定帧率。
延伸阅读:BIM 轻量化、三维引擎怎么选、数字孪生是什么,或看数字孪生专题。
要把数字孪生或数据大屏落进你的展厅、园区,还想让观众能上手点选、多屏联动?了解企服君自研 GoMagicWall 互动大屏——大屏可视化展示配多点触控交互,适配数据看板与展项联动。也可以直接说说现场需求,我们帮你定制方案、聊聊对接。
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。