80.不使用透明度隐藏UI组件

80.性能优化-GPU-UI系统优化-不使用透明度隐藏UI组件


80.1 知识点

知识回顾:隐藏 UI 元素的方式

在 UGUI 中,隐藏 UI 元素常见方式有:

  1. 通过 SetActive 设置 UI 元素所依附对象的激活/失活状态:会触发 Canvas 重建,恢复时也要重建,开销较大。
  2. 通过失活 UI 元素的图形组件:该元素不渲染,但仍会导致所在 Canvas 重建。
  3. 通过 CanvasGroup 组件将整体透明度改为 0
  4. 通过组件颜色属性将透明度改为 0
    方式 3 和 4 仍然会生成网格、送入渲染流程,GPU 依然在画,只是全透明。
  5. 通过将 Canvas(画布)组件失活:只禁用该 Canvas 的渲染器,其下所有 UI 元素不参与渲染和事件检测。

前面已强调过,通过禁用 Canvas 组件来隐藏 UI 是相对最省性能的做法;本节再强调一次:不要用透明度来“隐藏”组件。

为什么不要使用透明度隐藏组件

主要原因:用透明度“隐藏”的 UI 依然会参与完整渲染流程。

  1. 生成网格:UI 仍会生成顶点数据。
  2. 提交 DrawCallCanvasRenderer 仍会把看似隐藏的 UI 打包提交给 GPU。
  3. GPU 渲染:GPU 照常做光栅化、像素着色,只是最终混合结果为透明。也就是说,做了同样的计算,只是输出 alpha 为 0,肉眼看不见而已。
  4. 事件检测:若 Raycast Target = true,透明 UI 仍会参与射线检测,CPU 也有额外开销。

因此,用透明度“隐藏”时:看不见 ≠ 不渲染,只是画了一层看不见的内容。

归纳起来:CPU 消耗依旧、GPU 消耗依旧、事件检测消耗依旧。

如何尽量避免使用透明度隐藏组件

若要直接隐藏对象:

  • 首选:禁用该 UI 所在的 Canvas 组件。
  • 备选
    1. 失活 UI 图形组件(ImageRawImageText 等)。
    2. 失活该 UI 所依附的 GameObject。

若需要淡入淡出效果:
在透明度变为 0 的淡出结束后,再改用上述方式真正隐藏(禁用 Canvas 或失活组件/对象),而不是长期保持透明状态。


80.2 知识点代码

Lesson80_性能优化_GPU_UI系统优化_不使用透明度隐藏UI组件.cs

public class Lesson80_性能优化_GPU_UI系统优化_不使用透明度隐藏UI组件
{
    #region 知识回顾 隐藏UI元素的方式

    //在UGUI中,有以下几种方式可以隐藏UI元素
    //1.通过SetActive方法 设置UI元素依附对象的激活失活状态
    //  会触发 Canvas 重建,恢复时也要重建,开销较大
    //2.通过失活UI元素的 图形组件
    //  该元素不渲染,但仍会导致所在 Canvas 重建
    //3.通过CanvasGroup组件的整体改变透明度为0
    //4.通过组件颜色属性改变透明度为0
    //  3和4仍然会生成网格、送入渲染流程;
    //  GPU 依然在画,只是全透明
    //5.通过将Canvas(画布)组件失活
    //  只禁用这个 Canvas 的渲染器
    //  整个 Canvas 下 UI元素 不参与渲染和事件检测

    //我们在之前知识点中
    //就强调了通过禁用Canvas组件的方式隐藏组件是相对最节约性能的方式
    //这节课,我们再来强调一次不要使用透明度隐藏组件的相关知识

    #endregion

    #region 知识点一 为什么不要使用透明度隐藏组件

    //主要原因
    //透明度隐藏依旧会触发渲染
    //1.生成网格
    //  UI 元素依然会生成顶点数据
    //2.提交 DrawCall
    //  CanvasRenderer 还是会把看似隐藏的UI元素打包提交给 GPU
    //3.GPU渲染
    //  GPU 照常进行光栅化、像素着色,只是最终混合结果是透明像素
    //  也就是说,GPU 做了同样的计算,只是输出颜色的透明通道为0,看不到而已
    //4.事件检测
    //  如果 RaycastTarget = true,透明 UI 还会继续参与射线检测,CPU 也有性能浪费
    //所以如果通过透明度隐藏元素
    //看不见 ≠ 不渲染
    //它只是画了一个看不见的内容

    //原因:
    //1.CPU消耗依旧
    //2.GPU消耗依旧
    //3.事件检测消耗依旧

    #endregion

    #region 知识点二 如何尽量避免使用透明度隐藏组件

    //如果是想要直接隐藏对象
    //  最佳选择:
    //  禁用Canvas组件
    //  备用选择:
    //  1.失活UI图形组件(Image、RawImage、Text等)
    //  2.失活依附的GameObject对象

    //如果需要淡入淡出消失效果
    //  透明度为0淡出结束后,将其直接隐藏

    #endregion
}


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

×

喜欢就点赞,疼爱就打赏