<font size="4" style="line-height: 45px;" color="#c200ff"><strong>优化绘制调用</strong></font>
要将几何体绘制到屏幕上,Unity会向图形API发送绘制调用(Draw Call)。每个绘制调用包含图形API所需的所有信息(如纹理、着色器、缓冲区等)。虽然绘制调用本身可能消耗资源,但更耗资源的往往是其准备阶段——尤其是渲染状态(Render State)的变更(例如切换材质)。
<hr>
<font size="4" style="line-height: 45px;" color="#c200ff"><strong>为何优化绘制调用?</strong></font>
优化绘制调用和渲染状态变更的主要目标是提升帧率,同时带来以下优势:
1. 降低设备能耗:减少电量消耗(对移动设备尤为重要)和设备发热。
2. 提高项目可维护性:保持优化后,可向场景中添加更多GameObject而无需担心性能骤降。
<hr>
<font size="4" style="line-height: 45px;" color="#c200ff"><strong>优化方法</strong></font>
Unity提供多种优化策略,按优先级从高到低排序如下:
<font style="line-height: 40px;"><strong>1. SRP Batcher与静态批处理(Static Batching)</strong></font>
SRP Batcher:适用于使用可编程渲染管线(SRP)的项目。通过减少相同着色器变体的材质切换开销优化CPU性能。
静态批处理:预合并静态GameObject的网格。合并后每个网格仍独立渲染,但共享数据状态,降低每次调用的开销。
注意:静态批处理会覆盖GPU实例化。若检测到冲突,Unity编辑器会提示禁用静态批处理。
<font style="line-height: 40px;"><strong>2. GPU实例化(GPU Instancing)</strong></font>
适用场景:同网格重复出现(如树木、草丛)。
原理:单次绘制调用渲染多个实例,通过着色器传递每实例属性(如位置、颜色)。
<font style="line-height: 40px;"><strong>3. 动态批处理(Dynamic Batching)</strong></font>
原理:CPU动态合并共享相同配置(如顶点属性)的网格顶点,单次调用渲染。
限制:仅适用于小规模网格(顶点数通常不超过900)。
<font style="line-height: 40px;"><strong>4. 手动合并网格</strong></font>
方法:使用Mesh.CombineMeshes将多个网格合并为单个网格,减少绘制调用次数。
<hr>
<font size="4" style="line-height: 45px;" color="#c200ff"><strong>优化优先级与冲突处理</strong></font>
Unity按以下顺序优先应用优化方法(SRP Batcher除外,可与静态批处理共存):
1. SRP Batcher + 静态批处理
2. GPU实例化
3. 动态批处理
<font style="line-height: 40px;"><strong>冲突示例:</strong></font>
若GameObject启用静态批处理,即使其材质支持GPU实例化,Unity也会禁用实例化。
若GPU实例化可用,动态批处理将被禁用。
<hr>
<font size="4" style="line-height: 45px;" color="#c200ff"><strong>各方法对比与适用场景</strong></font>
<style type="text/css">
th{padding:5px;}
td{padding:5px;}
</style>
<table align="center" border="1" width="100%">
<tr><th>方法 适用场景</th><th>优点</th><th>缺点</th></tr>
<tr><td>SRP Batcher</td><td>SRP项目,同着色器变体材质</td><td>减少CPU准备开销</td><td>仅限SRP,需兼容的着色器结构</td></tr>
<tr><td>静态批处理</td><td>静态物体(如建筑、地形)</td><td>降低每调用开销,支持独立剔除</td><td>增加内存占用,不可动态修改</td></tr>
<tr><td>GPU实例化</td><td>大量重复网格(如植被、子弹)</td><td>高效渲染大量实例,节省CPU</td><td>需着色器支持,属性数量受限</td></tr>
<tr><td>动态批处理</td><td>小规模动态物体(如UI元素)</td><td>自动合并,无需预操作</td><td>顶点数限制,CPU计算开销</td></tr>
<tr><td>手动合并网格</td><td>复杂静态结构(如模块化场景资产)</td><td>完全控制,减少调用次数</td><td>失去独立剔除,增加内存占用</td></tr>
</table><br>
<hr>
<font size="4" style="line-height: 45px;" color="#c200ff"><strong>实施建议</strong></font>
分析性能瓶颈:使用Frame Debugger和Profiler确定绘制调用开销来源。
按优先级启用优化:优先尝试SRP Batcher和静态批处理,再考虑GPU实例化。
权衡内存与性能:静态批处理和手动合并会增大内存占用,需根据目标平台调整。
着色器适配:为需要GPU实例化的材质编写或修改着色器,添加实例化支持。
<hr>
<font color="#9a9a9a">版权声明:本文为CSDN博主「小李也疯狂」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。</font>
<a href="https://blog.csdn.net/qq_40882017/article/details/148145949"><font color="#9a9a9a">原文链接:https://blog.csdn.net/qq_40882017/article/details/148145949</font></a>
<br>