1. 碰撞网格基础

各位同学好,我是老张。在游戏引擎这行摸爬滚打了十几年,今天咱们来聊聊碰撞网格——这个看似基础、实则坑多到能让你加班到怀疑人生的东西。

说实话,我刚入行那会儿,对碰撞网格的理解就是「把模型扔给物理引擎就完事了」。结果呢?第一次做开放世界项目,场景里放了几百个道具箱,游戏跑起来帧率直接掉到个位数。老板站在我身后,那眼神……嗯,你们懂的。

从那以后,我才真正开始认真研究碰撞网格。今天这第一课,咱们就把基础打扎实。

什么是碰撞网格

碰撞网格,说白了就是物理引擎用来判断「物体之间有没有碰在一起」的几何数据。它不负责渲染,只负责计算。

你可以把它想象成一个物体的「骨架」——物理引擎拿着这个骨架去跟其他物体的骨架做碰撞检测。骨架越简单,算得越快;骨架越精细,算得越准。

我个人习惯把碰撞网格分成三类:

类型 描述 典型用途
原始碰撞体 球体、盒体、胶囊体 角色、子弹、简单道具
凸包网格 由凸多边形构成的封闭网格 家具、石块、车辆
三角网格 任意三角形网格(可凹可凸) 地形、建筑、复杂场景

这里有个关键点:碰撞网格不需要纹理、不需要法线贴图、不需要顶点颜色。它只需要顶点位置和三角形索引。就这么简单。

核心要点:碰撞网格只关心「形状」,不关心「长相」。物理引擎只看顶点和三角形,其他一切它都不在乎。

碰撞网格 vs 渲染网格

很多新手会把这两个概念搞混。我当年也犯过这个错——直接把高模的渲染网格扔给物理引擎,结果物理计算慢得像幻灯片。

咱们来看看它们到底差在哪:

对比维度 渲染网格 碰撞网格
顶点数 几万到几百万 几十到几千
数据内容 位置、法线、UV、切线、颜色 只有位置和三角形索引
精度要求 视觉上不能有瑕疵 物理上不能漏检/误检
拓扑结构 可开放、可非流形 必须封闭、必须流形
优化目标 视觉质量最大化 计算效率最大化

为什么会这样?因为渲染和物理是两套完全不同的计算管线。

渲染管线关心的是「每个像素该是什么颜色」,所以它需要法线算光照、需要UV贴纹理、需要切线做凹凸映射。而物理管线关心的是「两个物体有没有相交」,它只需要做几何求交运算——说白了就是算三角形跟三角形有没有重叠。

你想想看,一个角色模型可能有两万个三角形,但它的碰撞体可能只是一个胶囊体——两个半球加一个圆柱,总共不到一百个顶点。物理引擎处理这一百个顶点,比处理两万个顶点快了两个数量级。

我的经验:在项目中,我通常把渲染网格和碰撞网格的比例控制在 50:1 到 200:1 之间。也就是说,如果渲染网格有 10 万个三角形,碰撞网格最好控制在 500 到 2000 个三角形以内。超过这个范围,性能就开始吃紧了。

为什么需要简化

好,现在咱们来聊聊最核心的问题:为什么非要简化碰撞网格?直接用渲染网格不行吗?

答案是:不行,而且代价非常大。

我曾经在一个赛车游戏项目里做过测试:用原始高模做碰撞检测,每帧物理计算耗时约 12 毫秒;换成简化后的碰撞网格,同样的场景,耗时降到 0.8 毫秒。差了整整 15 倍。

简化碰撞网格的好处,我总结成三点:

  1. 性能提升——三角形越少,碰撞检测越快。物理引擎每帧要做成千上万次求交运算,少一个三角形,就少一次计算。
  2. 内存节省——碰撞网格数据要常驻内存。一个 10 万三角形的碰撞网格,光顶点位置和索引就要占好几 MB。场景里放几百个物体,内存就炸了。
  3. 稳定性增强——过于精细的碰撞网格容易产生「隧道效应」和「抖动问题」。简化后的网格反而更稳定,物理表现更可预测。

注意:简化不是无脑减面。过度简化会导致碰撞体与视觉模型严重不匹配,出现「明明看着撞上了,物理上却没反应」或者「明明看着没撞上,角色却被卡住了」的诡异问题。这种 bug 极难排查,我吃过不少亏。

那么,简化到什么程度才算合适?这里有个经验法则:

  • 玩家经常交互的物体(门、开关、可拾取道具):碰撞网格可以稍微精细一些,保证操作手感准确。
  • 场景装饰物(花盆、路灯、长椅):用凸包或者简化三角网格,保留大致轮廓即可。
  • 远景物体(远处的建筑、山体):直接用盒体或者球体,没人会注意到。
  • 地形:用高度图或者简化地形网格,不要用原始地形模型。

下面这张图展示了碰撞网格在整个物理系统中的位置和作用:

碰撞网格在物理系统中的角色 渲染网格 碰撞网格 简化算法 输入 输出 物理引擎 提供几何数据 碰撞检测 驱动计算 碰撞响应 输出结果 关键路径 渲染网格 → 简化 → 碰撞网格 → 物理引擎 → 碰撞检测 → 响应

从这张图可以看得很清楚:渲染网格经过简化算法处理后,变成碰撞网格,然后交给物理引擎做碰撞检测,最后输出碰撞响应。整个链条中,碰撞网格的质量直接决定了物理计算的效率和准确性。

好了,第一课就到这里。记住三个核心概念:碰撞网格是什么、它跟渲染网格有什么区别、为什么需要简化。后面我们会一步步深入,讲具体的简化算法和实战技巧。