72.性能优化-GPU-增强渲染性能-降低几何复杂度优化方向
72.1 知识点
为什么要降低几何复杂度
降低几何复杂度的主要目的是:
- 减轻 GPU 与 CPU 在几何处理阶段的负担。
- 减轻内存带宽压力和显存压力。
从 GPU 角度
GPU 渲染管线的第一步就是处理顶点。如果场景里有几百万甚至上千万个顶点,GPU 必须逐个变换(模型矩阵、光照计算、蒙皮等),负担会极大。可能带来:
- 帧率下降。
- 移动端功耗升高、发热严重。
- 顶点带宽不足导致 GPU 卡顿。
因此,降低几何复杂度,相当于直接减少了顶点着色器的工作量。
从 CPU 角度
每个网格渲染之前,CPU 要把网格数据提交给 GPU(DrawCall)。如果模型过于复杂(高面数、网格碎片多),则会导致 CPU 消耗在渲染准备工作上,挤占逻辑、物理计算上的时间。
因此,降低几何复杂度,可以间接减少 CPU 开销。
从显存角度
一般高面数模型文件更大,贴图需要更高分辨率支撑。高分辨率贴图以及顶点数据都需要占显存,可能给显存带来压力。
因此,降低几何复杂度,可以减轻显存压力。
从内存带宽角度
每帧都需要把顶点、顶点索引相关数据传送到 GPU。几何复杂度高会增加数据传输量,消耗内存带宽。
因此,降低几何复杂度,可以减少内存带宽的占用。
降低几何复杂度的具体方法
美术优化
从源头减少模型的复杂度,主要由美术人员在建模阶段直接控制。
主要做法:
- 少用高面数模型,能用贴图法线(Normal Map)代替细节就用贴图。
- 使用合理的多边形分布,把细分面留给容易注意到的部位。
主要目的就是用最少的资源做出最好的美术表现。从源头制定好的规范,可以让整体模型预算更加可控,避免后期出现性能问题时再来改。
移除网格
完全剔除不必要的几何体,避免 GPU 浪费处理不可见或者无关的网格。
主要做法:
- 删除关卡中看不到或不重要的装饰性几何体。
- 用法线贴图、贴花效果代替体积结构,比如雕刻、螺丝、砖块接缝等效果。
- 用平面贴图代替立体模型,比如窗户格子效果等。
主要目的就是优化关卡中装饰或远景模型。有时候牺牲一些细微表现,带给玩家的体验区别不大。
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