Unity 2021 LTS中着色器构建时间和内存使用的改进

news2024/11/6 7:35:06

随着Unity的可脚本渲染管道(SRP)的可用特性集的不断增长,在构建时处理和编译的着色器变量的数量也在不断增加。除了对更多图形api的持续支持和不断增长的目标平台选择外,SRP的改进还在继续扩展。

着色器在初始(“干净”)构建后被编译和缓存,从而加速进一步的增量(“温暖”)构建。虽然干净的构建通常需要最长的时间,但在项目开发和迭代过程中,冗长的温暖构建时间可能是一个常见的痛点。

图1: 在项目构建期间,着色器变体的处理和编译

为了解决这个问题,Unity的Shader管理团队一直在努力工作,提供有意义的和可扩展的解决方案。这大大减少了使用Unity 2021 LTS和更高版本创建的项目的着色器构建时间和运行时内存使用。

要关于这些新的优化,包括受影响的版本,后端端口,以及我们内部测试的数字,直接跳到涵盖着色器变量预过滤和动态着色器加载的部分。在这篇文章的最后,我们也谈到了我们未来的计划,进一步完善着色器变量管理作为一个整体-跨项目创作,构建和运行时。

在深入研究Unity着色器系统的令人兴奋的改进之前,让我们也利用这个机会快速回顾条件着色器编译、着色器变量和着色器变量剥离的概念。

条件着色器特性

条件着色器特性使开发人员和美工能够使用脚本、材质设置以及项目和图形设置方便地控制和改变着色器的功能。这样的条件特性有助于简化项目创作,允许项目通过最小化你必须创作和维护的着色器的数量来有效地扩展。

图2: 通过启用shader_feature关键字,艺术家在创作时启用了Clear Coat材质特性

条件着色器特性可以以不同的方式实现:

  1. 静态(编译时)分支

  1. Shader变量编译

  1. 动态(运行时)分支

虽然静态分支避免了运行时与分支相关的着色器执行开销,但它在编译时被评估和锁定,并且不提供运行时控制。同时,Shader变体编译是一种静态分支形式,提供额外的运行时控制。这是通过为每个可能的静态分支组合编译一个唯一的着色器程序(变体)来工作的,以便在运行时保持最佳的GPU性能。

这样的变量是通过shader_feature和multi_compile着色器关键字有条件地声明和评估着色器功能来创建的。正确的着色器变量在运行时根据活动关键字和运行时设置加载。声明和计算额外的着色器关键字会导致构建时间、文件大小和运行时内存使用的增加。

同时,动态(基于统一的)分支完全避免了着色器变体编译的开销,导致更快的构建,并减少了文件大小和内存使用。这可以在开发过程中带来更顺畅和更快的迭代。

另一方面,基于着色器的复杂性和目标设备,动态分支可以对着色器的执行性能产生强烈的影响。不对称分支(分支的一边比另一边复杂得多)会对性能产生负面影响。这是因为执行较简单的路径仍然会导致较复杂路径的性能损失。

当你在自己的着色器中引入条件着色器特性时,应该记住这些方法和权衡。有关更详细的信息,请参阅着色器条件,着色器分支和着色器变量文档。

着色器变型剥离

为了减少着色器处理和编译时间的增加,使用了着色器变量剥离。它的目的是排除不必要的着色器变量从编译基于因素,如:

  1. 材料包括和关键字启用

  1. 项目和渲染管道设置

  1. 脚本化的剥离

当枚举着色器变量时,编辑器将自动过滤掉任何使用shader_feature声明的关键字,这些关键字不是由构建中引用和包含的材料启用的。因此,这些关键字不会产生任何额外的变量。

例如,如果Clear Coat材质属性没有被使用Complex Lit URP Shader的任何材质启用,那么所有实现Clear Coat功能的Shader变体都将在构建时被安全地剥离。

同时,multi_compile关键字提示开发人员和玩家在运行时根据可用的播放器设置和脚本自由控制着色器的功能。另一方面,编辑器不能像shader_feature关键字那样自动剥离这些关键字。这就是为什么它们通常会产生更多的变种。

可脚本化剥离是一个c# API,它允许你在构建时通过关键字和运行时不需要的组合来排除编译中的着色器变量。渲染管道利用脚本化剥离,根据项目的渲染管道设置和构建中包含的质量资产剥离不必要的变量。

Low quality

High quality

Variant multiplier

Main Light/Cast Shadows:

Off

On

2x

Main Light/Cast Shadows:

On

On

1x

Main Light/Cast Shadows:

Off

Off

1x

为了最大化编辑器的着色器变量剥离的效果,我们建议禁用所有与图形相关的功能和渲染管道设置在运行时不使用。请参考官方文档更多关于着色器变体剥离。

着色器变量预过滤

基于构建中的渲染管道质量资产等因素,着色器变量剥离大大减少了编译着色器变量的数量。然而,剥离目前是在着色器处理阶段的末尾执行的。简单地列举所有可能的变量仍然需要很长时间,而不考虑编译。

为了减少着色器变量处理(和项目构建)时间,我们现在引入了一个重要的优化引擎的内置着色器变量剥离。使用着色器变体预过滤,干净和温暖的构建时间都显著减少。

根据渲染管道设置驱动的预过滤属性,通过引入早期排除multi_compile关键字来优化工作。这减少了为潜在的剥离和编译枚举的变量的数量,从而减少了着色器处理时间——在最激烈的例子中,暖构建时间减少了高达90%。

Shader变体预过滤在2023.1.0a14首次登陆,并已后移植到2022.2.0b15和2021.3.15f1。

图3: 着色器处理时间减少

图4: 着色器处理时间减少

通过应用相同的原理,变体预过滤还有助于减少初始/干净的构建时间。

图5; Shader变体预过滤清洁项目的建造时间

图6:项目构建减少着色器处理时间

动态着色器加载

从历史上看,Unity运行时在场景和资源加载期间会将所有着色器对象从磁盘预先加载到CPU内存中。在大多数情况下,一个构建的项目和场景包含比应用程序运行时任何给定时刻所需的更多的着色器变体。对于使用大量着色器的项目,这通常会导致在运行时使用大量着色器内存。

动态着色器加载通过提供精细的用户控制着色器加载行为和内存使用来解决这个问题。这种优化有助于将着色器数据块流到内存中,以及根据用户控制的内存预算,删除运行时不再需要的着色器数据。这允许你在内存预算有限的平台上显著减少着色器的内存使用。

新的着色器变量加载设置现在可以从编辑器的播放器设置中访问。使用它们来覆盖加载的着色器块的最大数量和每个着色器块大小(MB)。

图7: Editor > Project Settings > Player > Shader Variant Loading Settings

现在有了下面的c# API,你可以使用编辑器脚本覆盖着色器变量加载设置,比如:

  1. PlayerSettings。SetDefaultShaderChunkCount和PlayerSettings。

SetDefaultShaderChunkSizeInMB覆盖项目的默认着色器加载设置

  1. PlayerSettings。SetShaderChunkCountForPlatform和PlayerSettings。

SetShaderChunkSizeInMBForPlatform在每个平台上覆盖这些设置

你也可以在运行时使用c# API通过着色器. maximumchunksoverride来覆盖加载着色器块的最大数量。这使你能够根据运行时查询的总可用系统和图形内存等因素重写着色器内存预算。

动态着色器加载在2023.1.0a11登陆,并已反向移植到2022.2.0b10, 2022.1.21f1和2021.3.12f。在通用渲染管道(URP)的BoatAttack的情况下,我们观察到着色器的运行时内存使用减少了78.8%,从315 MiB(默认)到66.8 MiB(动态加载)。您可以在官方公告中关于此优化的信息。

图8: URP Boat Attack中使用的动态着色器加载,导致运行时着色器内存使用减少了78.8%。

接下来是什么?

除了上面提到的关键变化,我们正在努力增强通用渲染管道的着色器变体的生成和剥离。我们还在研究Unity的着色器变体管理的其他改进。最终目标是促进引擎不断增加的功能集,同时确保最小的着色器构建和运行时开销。

我们正在进行的一些调查涉及在相似的变体中重复删除着色器资源,以及对着色器关键字和着色器变体收集api的整体改进。目的是提供更多的灵活性和控制着色器变量处理和运行时性能。

展望未来,我们也在探索在编辑器中跟踪和分析着色器变量的可能性,以提供以下着色器变量使用的细节:

  1. 哪些着色器和关键字产生最多的变体?

  1. 哪些变量被编译但在运行时未使用?

  1. 哪些变量被剥离,但在运行时被请求?

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

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

相关文章

自动曝光在移动平台上的实现方案——以《使命召唤手游》为例

一. Intro在PBR渲染中,除了已被大家深入分析了很多遍的PBR材质属性(Surface Appearance)外,合理的光源强度和后处理也是不可或缺的部分。这里结合工作中的一些实践经验,讨论一下后处理中另一个关键环节——自动曝光在移…

Consul SpringCloudK8S

背景说起微服务,就需要用到SpringCloud,目前市面上主流的SpringCloud产品有这些:SpringCloudNeflix、Spring Cloud Alibaba、Spring Cloud for AWS、Spring Cloud Azure 和 Spring Cloud Kubernetes。其中SpringCloudNeflix已经不在更新&…

C#开发记录——C#开发的OPC客户端无法连接杰控软件的OPC服务器处理办法

1、某些OPC 客户端连接本地服务器失败 某些OPCDa 客户端,例如ABBDCS,.WinCC 等,本地连接服务器失败,需特殊设置; C#开发的就遇到此情况,排查原因,停滞了好几天,终于解决 1.1、打开DCOM 配置,64 位系统需执行: 1.2、从组件服务->计算机-&…

iOS UI自动化测试详解

前言: 小目标 关于UI自动化的定义,我想要的是自动地按照流程去点击页面、输入数据,不需要人去参与,节省人工时间。比如登录,能够自己去填写用户名&密码,然后点击按钮跳转到下一个页面等。在能够保证业…

pandas表格并表(累加合并)

今天需求是用pandas的两张表格合并起来,其中重复的部分将数据进行相加。 用到的是combine()这个函数。 函数详细的使用可以看这个大佬的文章: https://www.cnblogs.com/traditional/p/12727997.html (这个文章使用的测…

vue之为什么data属性是一个函数而不是一个对象?

为什么data属性是一个函数而不是一个对象为什么data属性是一个函数而不是一个对象?一、实例和组件定义data的区别二、组件data定义函数与对象的区别三、原理分析四、结论为什么data属性是一个函数而不是一个对象? 一、实例和组件定义data的区别 vue实例…

嵌入式物联网【数据处理篇】特殊字符处理(Postman 400 Bad Request)

目录 一、Postman 400 Bad Request 二、C语言特殊字符处理 三、QUrl toPercentEncoding 处理url中含有特殊字符转码 16进制ASCII码对照表 一、Postman 400 Bad Request http请求链接中的特殊字符处理 解决包括Postman 中的post、get等链接请求中的特殊字符(如…

谷歌关键词优化多少钱【2023年调研】

本文主要分享Google关键词排名优化的一些成本调研,方便大家参考。 本文由光算创作,有可能会被剽窃和修改,我们佛系对待这种行为吧。 今年2023年了,谷歌关键词优化到底要多少钱? 答案是:价格在2w~25w左右…

c++终极螺旋丸:₍˄·͈༝·͈˄*₎◞ ̑̑“类与对象的结束“是结束也是开始

文章目录 前言一.构造函数中的初始化列表 拷贝对象时的一些编译器优化二.static成员三.友元四.内部类总结前言 前两期我们将类和对象的重点讲的差不多了,这一篇文章主要进行收尾工作将类和对象其他的知识点拉出来梳理一遍,并且补充前两篇没有讲过的…

第3集丨Java中的异常、处理方式及自定义异常汇总

目录一、异常的分类1.1 常见的运行时异常1.2 常见的检查异常1.3 继承关系二、异常处理机制三、try…catch…finally四、声明抛出异常五、人工抛出异常六、自定义异常任何一种程序设计语言设计的程序在运行时都有可能出现错误,例如除数为0,数组下标越界&a…

别学英语了,真的

文 / 王不留(微信公众号:王不留) 这两年,很多朋友加我微信后,第一句常是,学英语有什么用啊? 我会统一给出真诚答复:没用,真的。 看新闻,中文海量信息已经严重…

建筑行业固定资产管理解决方案

建筑行业的固定资产种类和数量都较多,常用的固定资产有:办公设备、机械、设备、工具等。设备的调拨、购置、测试、验收、建帐立卡、分类编号、技术档案、供应分配、清查盘点、提取折旧、报废、设备维修、设备保养、备件管理、设备巡检和点检等工作&#…

S7-1200对于不同项目下的PLC之间进行开放式以太网通信的具体方法示例

S7-1200对于不同项目下的PLC之间进行开放式以太网通信的具体方法示例 如下图所示,打开TIA博途创建一个新项目,并通过“添加新设备”组态 S7-1200 客户端 ,选择 CPU1214C DC/DC/DC (client IP:192.168.0.102),建立新子网; 首先编写客户端程序:打开OB1编程界面,选择指令…

图片如何提取文字?

在当今信息爆炸的时代,图文并茂已经成为了一个广告宣传的常用方式。然而,图片中的文字信息往往难以获取,尤其对于那些需要快速获取信息的人们来说,阅读图片中的文字会是一项繁琐且费时的任务。现在,我们有一个好消息要…

如何熟练掌握Python在气象水文中的数据处理及绘图【免费教程】

pythonPython由荷兰数学和计算机科学研究学会的吉多范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多…

[python课程设计1]学生成绩管理系统

引言本课程设计使用数据库,熟悉了Python语言操作数据库,对数据库的增删改查,实现Qt designer界面设计以及excel表格的读写,代码通俗易懂,方便对所学知识的掌握。需求分析用类对学生成绩、代码封装使得操作使用简单&…

java开启线程的四种方法

文章目录1、继承Thread类1.1 代码实现1.2 测试结果2、实现Runnable接口2.1 方式一:直接实现Runnable接口2.1.1 代码实现2.1.2 测试结果2.2 方式二:匿名内部类2.2.1 代码实现2.2.2 测试结果3、实现Callable接口3.1 代码实现3.2 测试结果4、创建线程池4.1 …

常见帧率计算方法实际效果对比及EasyCVR平台的帧率计算方法

什么是帧、帧数、帧率? 帧 (Frame) 帧可以理解为视频或者动画中的每一张画面,而视频和动画特效是由无数张画面组合而成,每一张画面都是一帧。 帧数(Frames) 帧数是帧生成的数量。如果一个动画…

Scala 变量和数据类型(第二章)

第二章、变量和数据类型2.1 注释2.2 变量和常量(重点)2.3 标识符的命名规范2.4 字符串输出2.5 键盘输入2.6 数据类型(重点)回顾:Java数据类型Scala数据类型2.7 整数类型(Byte、Short、Int、Long&#xff09…

OpenAI CEO喊麦ChatGPT:你很酷,但却是个“糟糕的产品”

OpenAI 联合创始人兼CEO山姆阿尔特曼(Sam Altman)最近在一档播客节目中称ChatGPT 为“糟糕的产品”。 阿尔特曼说,“人们访问的是一个有时能用,有时不能用的网站。”他指的是ChatGPT频繁出现的错误消息。 他补充说道:…