UGUI优化篇(更新中)

UGUI优化篇

  • 1. 基础概念
  • 2. 重要的类
    • 1. MaskableGraphic类继承了IMaskable类
    • 2. 两种遮罩的实现区别
      • RectMask2D
      • Mask
  • 3. 渲染部分知识
    • 深度测试
      • 深度测试的工作原理
    • 渲染队列
      • 透明物体在渲染时怎么处理
      • 为什么透明效果会造成性能问题

1. 基础概念

  • 所有UI都由网格绘制的
  • 如image由两个三角形构成,四个顶点
    在这里插入图片描述
    在这里插入图片描述
  • drawcall(绘制调用)是指向GPU发送绘制指令的过程。每个draw call都是一次向图形处理器提交渲染命令的操作。具体来说,每当Unity需要绘制一个物体或一批物体时,它会生成一个或多个draw call。
  • 填充率(Fill Rate)是指图形处理器(GPU)能够每秒填充像素的数量。它通常用来衡量GPU的渲染能力和性能。
  • 屏幕的分辨率决定了需要渲染的像素数量。更高的分辨率意味着需要填充更多的像素,因此会影响填充率。
  • Overdraw指的是在渲染过程中多次绘制同一个像素的现象。这通常发生在复杂的场景中,特别是当许多物体重叠或者遮挡彼此时。
  • 在Overdrall模式下,可以看到重叠的部分,两次drawcall,同一像素被绘制两次
    在这里插入图片描述
  • 批处理(Batching)是一种优化技术,用于减少向图形处理器(GPU)发送的绘制调用(draw call)数量。每个draw call都是向GPU发送绘制命令的操作,而过多的draw call会增加CPU和GPU的负载,可能导致性能下降。
  • Unity中有静态批处理和动态批处理。静态批处理适用于不会移动或改变的物体,而动态批处理适用于能够共享相同材质的移动物体。这些技术可以减少draw call数量,提高性能。
  • 在这个例子中,两个image会有两次绘制调用drawcall,重叠的部分绘制的两次,可以将两个网格合并成一个网格,最后,在渲染时,只需要发送一个绘制调用drawcall来渲染一个网格,而不是每个image一个绘制调用。这样就大大减少了CPU发送绘制命令的开销,也减少了GPU处理多个绘制调用的开销。

在这里插入图片描述

2. 重要的类

1. MaskableGraphic类继承了IMaskable类

  • 继承MaskableGraphic类的组件都可以被mask进行一个遮挡
    在这里插入图片描述

2. 两种遮罩的实现区别

RectMask2D

在这里插入图片描述
IClipper接口是有一个剪切的方法

public interface IClipper
{/// <summary>/// Function to to cull / clip children elements./// </summary>/// <remarks>/// Called after layout and before Graphic update of the Canvas update loop./// </remarks>void PerformClipping();
}

Mask

在Mask有一个方法GetModifiedMaterial,用模板缓存实现遮罩

/// Stencil calculation time!
public virtual Material GetModifiedMaterial(Material baseMaterial)
{if (!MaskEnabled())return baseMaterial;var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas);if (stencilDepth >= 8){Debug.LogWarning("Attempting to use a stencil mask with depth > 8", gameObject);return baseMaterial;}int desiredStencilBit = 1 << stencilDepth;// if we are at the first level...// we want to destroy what is thereif (desiredStencilBit == 1){var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0);StencilMaterial.Remove(m_MaskMaterial);m_MaskMaterial = maskMaterial;var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0);StencilMaterial.Remove(m_UnmaskMaterial);m_UnmaskMaterial = unmaskMaterial;graphic.canvasRenderer.popMaterialCount = 1;graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);return m_MaskMaterial;}//otherwise we need to be a bit smarter and set some read / write masksvar maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));StencilMaterial.Remove(m_MaskMaterial);m_MaskMaterial = maskMaterial2;graphic.canvasRenderer.hasPopInstruction = true;var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));StencilMaterial.Remove(m_UnmaskMaterial);m_UnmaskMaterial = unmaskMaterial2;graphic.canvasRenderer.popMaterialCount = 1;graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);return m_MaskMaterial;
}
  • 因为两种遮罩实现不同,进行UI优化也不同

3. 渲染部分知识

深度测试

深度测试(Depth Testing)是指用于确定哪些像素应该显示在其他像素之上的一种技术。起到剔除优化的作用。

深度测试的工作原理

通过比较每个像素的深度值(Depth Value)来确定像素是否应该被渲染。深度值是从相机到像素的距离的反映,通常是从0(最近)到1(最远)的范围。具体来说:

  1. 深度缓冲(Depth Buffer):
  • 在渲染每个像素之前,Unity会将每个像素的深度值写入到一个称为深度缓冲(Depth Buffer)的特殊缓冲区中。
  • 深度缓冲是一个与屏幕大小相同的二维数组,每个元素存储与像素位置对应的深度值。
  1. 深度测试的执行:
  • 当一个物体的像素要渲染到屏幕上时,Unity会首先将该像素的深度值与深度缓冲中对应像素的深度值进行比较。
  • 如果当前像素的深度值小于深度缓冲中的深度值(即当前像素更接近相机),则该像素被渲染,并更新深度缓冲。
  • 如果当前像素的深度值大于深度缓冲中的深度值(即当前像素在深度上在后面),则该像素被丢弃,不会渲染到屏幕上。

渲染队列

渲染队列(Rendering Queue)是一个用来管理和排序需要被渲染的物体、几何体或者图形效果的机制。渲染队列的目的是为了优化渲染流程,确保图形处理单元(GPU)以最高效的方式处理和渲染场景中的各个元素。

透明物体在渲染时怎么处理

透明物体在渲染时主要采取从后向前(back-to-front)的渲染顺序。这是因为透明物体不会写入深度缓冲(depth buffer),也就是说它们不会遮挡其他物体,因此渲染的顺序决定了它们如何叠加在一起。

  1. 排序:首先,将所有需要渲染的透明物体按照它们在场景中的深度(通常是距离观察者的距离)进行排序。
  2. 从后向前渲染:按照排序后的顺序,从距离观察者最远的透明物体开始渲染,逐渐向前渲染到距离观察者最近的物体。
  3. 混合:在渲染每个透明物体时,使用Alpha混合(Alpha blending)技术将当前物体的颜色与已经渲染到屏幕上的颜色进行混合。这通常涉及到将当前物体的颜色和Alpha值(表示透明度的值)与屏幕上的颜色和Alpha值进行某种计算,得到新的颜色和Alpha值。
  4. 关闭深度写入:由于透明物体不会写入深度缓冲,因此需要确保在渲染透明物体时关闭深度写入功能,以避免它们错误地遮挡其他物体。
  5. 开启深度测试:虽然透明物体不会写入深度缓冲,但仍然需要开启深度测试来确保它们正确地叠加在其他不透明的物体之上。

通过这种方法,可以确保透明物体在渲染时能够正确地叠加在一起,并产生正确的视觉效果。

为什么透明效果会造成性能问题

透明效果会造成性能问题,主要是因为它们涉及到Alpha混合(Alpha blending)和渲染顺序(通常是从后向前)的处理,这会导致以下几个方面的性能开销:

  1. Overdraw(过度绘制):当一个像素被多次绘制时,就发生了overdraw。对于不透明物体,由于深度测试(depth testing)的存在,只有离观察者最近的物体会被绘制到屏幕上,因此overdraw通常不是问题。但对于透明物体,由于它们不会写入深度缓冲,并且需要按照从后向前的顺序渲染,所以每个透明物体都会与已经绘制在屏幕上的颜色进行混合,这可能导致一个像素被多次绘制和混合。
  2. 排序开销:为了正确渲染透明物体,需要将它们按照从后向前的顺序进行排序。这个排序过程可能涉及到大量的计算,特别是对于动态场景中的大量透明物体。
  3. Alpha混合的计算开销 :Alpha混合是一个相对复杂的计算过程,需要将当前像素的颜色和Alpha值与屏幕上的颜色和Alpha值进行混合。这个过程比简单的不透明渲染要复杂得多,因此会增加GPU的计算负担。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode(经典题)day4

滑动窗口 长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 使用滑动窗口&#xff0c;当前窗口大小的数组的和比目标值小就加大窗口&#xff08;r&#xff09;&#xff0c;当前窗口大小的数组的和比目标值大或相等&#xff0c;就减小窗口大小…

力扣题解(不同的子序列)

115. 不同的子序列 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 109 7 取模。 思路&#xff1a; 本题研究的是t在s中出现的次数&#xff0c;注意t一定是小的那个&#xff0c;是s的子串。 dp[i][j]表示t的&#xff…

25届平安产险校招测评IQ新16PF攻略:全面解析与应试策略

尊敬的读者&#xff0c;您好。随着平安产险校招季的到来&#xff0c;许多应届毕业生正积极准备着各项测评。本文旨在提供一份详尽的测评攻略&#xff0c;帮助您更好地理解平安产险的校招测评流程&#xff0c;以及如何有效应对。 25届平安产险平安IQ&#xff08;新&#xff09;测…

AI大模型探索之旅:深潜大语言模型的训练秘境

在人工智能的浩瀚星空中&#xff0c;大语言模型无疑是最耀眼的星辰之一&#xff0c;它们以无与伦比的语言理解与生成能力&#xff0c;引领着智能交互的新纪元。本文将带您踏上一场探索之旅&#xff0c;深入大语言模型的训练秘境&#xff0c;揭开其背后复杂而精妙的全景画卷。 …

Java常用API---Object类

Object类概述 概述 Object类是所有类的父类&#xff0c;任何一个类的对象(包括数组)&#xff0c;都可以调用Object类的方法 目标: 掌握Object类的常用方法 常用方法&#xff1a; boolean equals(Object obj)&#xff1a;判断当前对象是否与参数对象"相等" Strin…

Linux时间查看和设置

查看时间 date 命令&#xff0c;输出 Sun Jul 14 07:23:03 PM CST 2024timedatectl 命令&#xff0c;输出 Local time: Sun 2024-07-14 10:30:00 CSTUniversal time: Sun 2024-07-14 02:30:00 UTCRTC time: Sun 2024-07-14 02:30:00Time zone: Asia/Shanghai (CST, 0800) Sys…

汇编学习基础知识【记录】

前言 又是快乐的学习汇编的一天&#xff0c;时间如白驹过隙&#xff0c;抓紧时间&#xff0c;在学习能力最好的年纪多学习一些知识&#xff0c;朝着美好生活而奋斗&#xff01;哈哈哈 参考文章&#xff1a; https://blog.csdn.net/Z_H_Z_0/article/details/106574292 知识补…

给 「大模型初学者」 的 LLaMA 3 核心技术剖析

编者按&#xff1a; 本文旨在带领读者深入了解 LLaMA 3 的核心技术 —— 使用 RMSNorm 进行预归一化、SwiGLU 激活函数、旋转编码&#xff08;RoPE&#xff09;和字节对编码&#xff08;BPE&#xff09;算法。RMSNorm 技术让模型能够识别文本中的重点&#xff0c;SwiGLU 激活函…

现在有哪些微服务解决方案?

Dubbo&#xff1a;是一个轻量级的Java微服务框架&#xff0c;最初由阿里巴巴在2011年开源。它提供了服务注册与发现、负载均衡、容错、分布式调用等。Dubbo更多的被认为是一种高性能的RPC框架&#xff08;远程过程调用&#xff09;&#xff0c;一些服务治理功能依赖第三方组件完…

以一个springboot项目中创建用户会话的业务背景来说明threadlocal的用法

在Spring Boot项目中&#xff0c;ThreadLocal 是一个非常有用的工具&#xff0c;特别是在处理用户会话信息时。ThreadLocal 允许你在同一个线程中存储和访问变量&#xff0c;而不会与其他线程的变量发生冲突。这对于存储用户会话信息、请求上下文等非常有用。 以下是一个示例&…

第一部分:C++入门

目录 前言 1、C关键字(C98) 2、命名空间 2.1、命名空间定义 2.2、命名空间的使用 3、C输入&输出 4、缺省参数 4.1、缺省参数的概念 4.2、缺省参数的分类 5、函数重载 5.1、函数重载的概念 5.2、C支持函数重载的原理 6、引用 6.1、引用的概念 6.2、引用特性 …

Unity与Unreal Engine:AR建筑应用开发之选

在AR技术的浪潮中&#xff0c;建筑行业正迎来一场技术革新。对于希望为建筑工人开发AR应用的创业者来说&#xff0c;选择正确的开发平台至关重要。本文将基于社区讨论&#xff0c;深入分析Unity与Unreal Engine两款引擎在AR施工应用中的优劣&#xff0c;为开发者提供决策参考。…

深圳晶彩智能JC3636W518C开箱实现电脑副屏功能

深圳晶彩智能发布了JC3636W518C 这是一款中国制造的&#xff0c;铝合金外壳&#xff0c;价格非常震撼的开发板。原创是billbill的up播主萨纳兰的黄昏设计的ESP32太极小派&#xff0c;由深圳晶彩智能批量生产。 该款 LCD 模块采用 ESP32-S3R8 芯片作为主控,该主控是双核 MCU&…

LightDM和SDDM显示管理器学习小知识

LightDM和SDDM是两种不同的显示管理器&#xff08;Display Manager&#xff09;&#xff0c;它们可以与多种Linux桌面环境配合使用。以下是它们常见的对应关系&#xff1a; ### LightDM LightDM是一个跨桌面的显示管理器&#xff0c;它允许用户选择不同的桌面环境。以下是一些…

C++入门基础篇(2)

欢迎大家的来到小鸥的博客&#xff0c;今天我们继续C基础的第二篇吧&#xff01; 这也是入门基础篇的最后一篇wo~ 目录 1.引用 引用的概念 引用的特性及使用 const常引用 指针和引用的关系 2.inline内联函数 定义 相关特性及使用​ 3.nullptr >>后记<< …

摩尔投票算法

文章目录 什么是摩尔投票算法算法思想 相关例题摩尔投票法的扩展题目解题思路代码奉上 什么是摩尔投票算法 摩尔投票法&#xff08;Boyer-Moore Majority Vote Algorithm&#xff09;是一种时间复杂度 为O(n),空间复杂度为O(1)的方法&#xff0c;它多数被用来寻找众数&#xf…

深入理解Symfony框架中的数据验证机制

Symfony是一个高度灵活的PHP Web应用框架&#xff0c;它提供了一整套工具和实践来帮助开发者构建复杂的Web应用。数据验证是确保应用数据完整性和安全性的关键环节。在Symfony中&#xff0c;数据验证是通过一系列的组件和方法来实现的&#xff0c;这些组件和方法遵循DRY&#x…

Manim的代码练习02:在manim中Dot ,Arrow和NumberPlane对象的使用

Dot&#xff1a;指代点对象或者表示点的符号。Arrow&#xff1a;指代箭头对象&#xff0c;包括直线上的箭头或者向量箭头等。NumberPlane&#xff1a;指代数轴平面对象&#xff0c;在Manim中用来创建包含坐标轴的数学坐标系平面。Text&#xff1a;指代文本对象&#xff0c;用来…

Linux系列--命令详解

目录 一、Linux资源管理方式 二、查询类型命令详解 三、文件管理类型命令详解 四、文件压缩与解压 五、文件编辑 六、系统命令 七、文件内容查看命令 一、Linux资源管理方式 linux操作系统采用一个文档树来组织所有的资源。这棵树的根目录的名字叫做&#xff1a;//…

使用 HttpServlet 接收网页的 post/get 请求

前期工作&#xff1a;部署好 idea 和 一个 web 项目 idea(2021),tomcat(9) ->创建一个空的项目 -> 新建一个空的模块 -> 右键单击模块 选择 Add..Fra.. Sup.. -> 勾选Web App...后点击OK -> 点击 file - Project Struc... -> 选择刚刚的模块 -> 点…