72.降低几何复杂度优化方向

72.性能优化-GPU-增强渲染性能-降低几何复杂度优化方向


72.1 知识点

为什么要降低几何复杂度

降低几何复杂度的主要目的是:

  1. 减轻 GPU 与 CPU 在几何处理阶段的负担。
  2. 减轻内存带宽压力和显存压力。

从 GPU 角度

GPU 渲染管线的第一步就是处理顶点。如果场景里有几百万甚至上千万个顶点,GPU 必须逐个变换(模型矩阵、光照计算、蒙皮等),负担会极大。可能带来:

  1. 帧率下降。
  2. 移动端功耗升高、发热严重。
  3. 顶点带宽不足导致 GPU 卡顿。

因此,降低几何复杂度,相当于直接减少了顶点着色器的工作量。

从 CPU 角度

每个网格渲染之前,CPU 要把网格数据提交给 GPU(DrawCall)。如果模型过于复杂(高面数、网格碎片多),则会导致 CPU 消耗在渲染准备工作上,挤占逻辑、物理计算上的时间。
因此,降低几何复杂度,可以间接减少 CPU 开销。

从显存角度

一般高面数模型文件更大,贴图需要更高分辨率支撑。高分辨率贴图以及顶点数据都需要占显存,可能给显存带来压力。
因此,降低几何复杂度,可以减轻显存压力。

从内存带宽角度

每帧都需要把顶点、顶点索引相关数据传送到 GPU。几何复杂度高会增加数据传输量,消耗内存带宽。
因此,降低几何复杂度,可以减少内存带宽的占用。

降低几何复杂度的具体方法

美术优化

从源头减少模型的复杂度,主要由美术人员在建模阶段直接控制。

主要做法:

  1. 少用高面数模型,能用贴图法线(Normal Map)代替细节就用贴图。
  2. 使用合理的多边形分布,把细分面留给容易注意到的部位。

主要目的就是用最少的资源做出最好的美术表现。从源头制定好的规范,可以让整体模型预算更加可控,避免后期出现性能问题时再来改。

移除网格

完全剔除不必要的几何体,避免 GPU 浪费处理不可见或者无关的网格。

主要做法:

  1. 删除关卡中看不到或不重要的装饰性几何体。
  2. 用法线贴图、贴花效果代替体积结构,比如雕刻、螺丝、砖块接缝等效果。
  3. 用平面贴图代替立体模型,比如窗户格子效果等。

主要目的就是优化关卡中装饰或远景模型。有时候牺牲一些细微表现,带给玩家的体验区别不大。

LOD

利用 Unity 中的 LOD Group 组件,根据距离切换不同分辨率的模型网格。LOD 模型通常由美术导出(也可以利用一些插件自己生成),配合摄像机视距控制显示哪一个模型。

主要做法:
让游戏中的角色、建筑、大型场景元素使用 LOD Group 组件关联不同精度的模型,这样能显著减少远处对象的顶点数。

遮挡剔除

利用 Unity 中自带的遮挡剔除(Occlusion Culling)相关功能,避免渲染那些被其他物体完全挡住、相机不可见的物体,从而减少 GPU 和 CPU 的渲染开销。

主要做法:
在一些容易产生遮挡的环境中,比如室内场景、复杂建筑场景、森林场景等,使用 Unity 中的遮挡剔除功能,剔除在墙体、地形、树木等背后的对象,让它们不被渲染,减少渲染开销。

更多方式

以下这些方法,可能会影响美术表现效果。

1. 简化骨骼动画
骨骼数量过多时,GPU 和 CPU 负担都重。可以减少关节数,或者用 VAT(骨骼烘焙动画纹理)代替。

2. Impostor(替身)技术
把一个复杂的 3D 物体预先烘焙成 2D 纹理,用 2D 贴图来冒充 3D 模型。可以配合 LOD 使用:

  • 近距离,使用正式的 3D 模型。
  • 中远距离,使用低模 LOD。
  • 超远距离,使用 Impostor(替身)技术。

3. Mesh Simplification(网格简化算法)
美术在建模时,使用一些建模软件自带的网格简化功能。Unity 也有一些第三方插件,比如:


72.2 知识点代码

Lesson72_性能优化_GPU_增强渲染性能_降低几何复杂度优化方向.cs

public class Lesson72_性能优化_GPU_增强渲染性能_降低几何复杂度优化方向
{
    #region 知识点一 为什么要降低几何复杂度

    //降低几何复杂度的主要目的是
    //1.减轻 GPU 与 CPU 在几何处理阶段的负担
    //2.减轻 内存带宽 压力和 显存 压力

    //从GPU角度
    //GPU 渲染管线的第一步就是处理顶点
    //如果场景里有几百万甚至上千万个顶点
    //GPU 必须逐个变换(模型矩阵、光照计算、蒙皮等)
    //负担会极大
    //可能带来
    //1.帧率下降
    //2.移动端功耗升高、发热严重
    //3.顶点带宽不足导致 GPU 卡顿
    //因此,降低几何复杂度,相当于直接减少了顶点着色器的工作量

    //从CPU角度
    //每个网格渲染之前,CPU 要把网格数据提交给 GPU(DrawCall)
    //如果模型过于复杂(高面数、网格碎片多)
    //则会导致CPU消耗在渲染准备工作上
    //挤占逻辑、物理计算上的时间
    //因此,降低几何复杂度,可以间接减少CPU开销

    //从显存角度
    //一般高面数模型文件更大,贴图需要更高分辨率支撑
    //高分辨率贴图以及顶点数据都需要占显存
    //可能给显存带来压力
    //因此,降低几何复杂度,可以减轻显存压力

    //从内存带宽角度
    //每帧都需要把顶点、顶点索引相关数据传送到GPU
    //几何复杂度高会增加数据传输量,消耗内存带宽
    //因此,降低几何复杂度,可以减少内存带宽的占用

    #endregion

    #region 知识点二 降低几何复杂度的具体方法

    #region 1.美术优化

    //从源头减少模型的复杂度,主要由美术人员在建模阶段直接控制
    //主要做法:
    //1.少用高面数模型,能用贴图法线(Normal Map)代替细节就用贴图
    //2.使用合理的多边形分布,把细分面留给容易注意到的部位
    //主要目的就是用最少的资源做出最好的美术表现
    //从源头制定好的规范,可以让整体模型预算更加可控
    //避免后期出现性能问题时再来改

    #endregion

    #region 2.移除网格

    //完全剔除不必要的几何体,避免GPU浪费处理不可见或者无关的网格
    //主要做法:
    //1.删除关卡中看不到或不重要的装饰性几何体
    //2.用法线贴图、贴花效果代替体积结构,比如雕刻、螺丝、砖块接缝等效果
    //3.用平面贴图代替立体模型,比如窗户格子效果等
    //主要目的就是优化关卡中装饰或远景模型
    //有时候牺牲一些细微表现,带给玩家的体验区别不大

    #endregion

    #region 3.LOD

    //利用Unity中的LOD Group组件
    //根据距离切换不同分辨率的模型网格
    //LOD 模型通常由美术导出(也可以利用一些插件自己生成)
    //配合摄像机视距控制显示哪一个模型
    //主要做法:
    //让游戏中的角色、建筑、大型场景元素使用LOD Group组件关联不同精度的模型
    //这样能显著减少远处对象的顶点数

    #endregion

    #region 4.遮挡剔除

    //利用Unity中自带的遮挡剔除(Occlusion Culling)相关功能
    //避免渲染那些被其他物体完全挡住、相机不可见的物体
    //从而减少 GPU 和 CPU 的渲染开销
    //主要做法:
    //在一些容易产生遮挡的环境中,比如室内场景、复杂建筑场景、森林场景等
    //使用Unity中的遮挡剔除功能,剔除在墙体、地形、树木等背后的对象
    //让它们不被渲染,减少渲染开销

    #endregion

    #region 5.更多方式

    //以下这些方法,可能会影响美术表现效果
    //5-1.简化骨骼动画
    //    骨骼数量过多时,GPU和CPU负担都重
    //    可以减少关节数,或者用 VAT(骨骼烘焙动画纹理)代替
    //5-2.Impostor(替身)技术
    //    把一个复杂的 3D 物体 预先烘焙成 2D 纹理
    //    用 2D 贴图来冒充 3D 模型
    //    可以配合LOD使用
    //    近距离,使用正式的3D模型
    //    中远距离,使用低模LOD
    //    超远距离,使用Impostor(替身)技术
    //5-3.Mesh Simplification(网格简化算法)
    //    美术在建模时,使用一些建模软件自带的网格简化功能
    //    Unity也有一些第三方插件,比如
    //    RMS(Runtime Mesh Simplifier)
    //    Mesh Simplify

    #endregion

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏