又被Unity坑了一把,简单说下吧,下面都是流水账,结论就写在最后了,就是Unity5 - 5.2的shader编译机制真是不咋地。

1.Why Always me?

问题是这样的,我照着Unity5 的Standard shader写了一个给我们工程用的简化版的标准Shader以及配合使用的ShadergGUI,里面融合了很多功能,包括支持法线啊、uv动画啊、半透镂空等等,通过shader_feature定义的宏将这些效果融合到一个shader里,这样既方便了美术,也方便了shader的管理,不用像原来一样工程里乱七八糟的一堆shader了。

不过后期在真机测试的时候遇到了一个问题,就是我通过EnableKeyword来动态修改材质表现在设备上不好使了。当时第一想法就是Shader中那么多条件宏在build的时候被Unity自动strip掉了,因为我们大部分的资源都打包成了Assetbundle包,工程实际只有一个空场景,Shader资源都放在了Resources目录下。如果说因为build的场景和资源里不包含shader的一些variant而被Unity自动去掉了这也是可以理解的。于是我就想GraphicsSettings里不是有个Always Included Shaders么,按照字面意思理解把shader放到那里去总是可以了吧,于是我就按下图设置了下。嘿!还真就好了!

2.100MB WTF?

既然这样好了,那看来真机调试时其他的一些问题比如角色表现增强效果应该也是这个原因喽,那索性把其他的shader也都加进来吧,省的后面再出问题。别说这招真是包治百病,单机界面里我们还用了不少Standar shader,也就添加进来吧。ok,一切问题解决。。。。。。了吗?
第二天测试就告诉我这个版本闪退频繁,一查都是内存爆了。拿Instrument一看我靠,一登录就快300MB了,看下Allocation,编译Shader居然就用了100多MB。难道说跟昨天把Standard Shader加进去导致的?虽然是很怀疑不过既然调试已经定位到这里还是试一下吧,于是乎把Standard shader从Always Included Shaders列表中移除再发布,嘿!还真就好了!

3.真相水落石出

现在的情况就是
1.真机运行时Shader.EnableKeyword不好使,应该是因为Unity在Build时自动把没有用到的variant删减掉了(不是结论)
2.通过Always Included Shaders设置解决了问题,不过导致内存大量增加,应该是因为Unity在启动时把该列表内的Shader的全部variant都展开编译了出来,所以一方面解决了上面的问题,一方面却增大了内存,而至于内存为什么会增加如此之多,那只能靠猜的了。
既然这样,那就要想办法解决Shader的内存占用了,既然全部variant占据的空间太大就部分加载呗,正好Unity5增加了个ShaderVariantCollection这么个东西,看看好不好用。结果。。。。。多天的各种实验全部以失败告终,这包括:
1.创建ShaderVariantCollection资源,包含目标shader的全部variant,并添加到GraphicsSettings的Preload Shaders列表中
2.通过代码创建ShaderVariantCollection,并调用WarmUp接口

=========================流水账分割线==================================

下面总结下我分析出来的Unity5.0 - 5.2的Shader编译加载策略
1. 发布工程时,Unity 会将全部multi_compile定义宏组合成的variant编译并加入包中
2. 发布工程时,Unity 会将全部关联材质引用到的variant编译并加入包中
3. 发布工程时,Unity会将Always Included Shaders列表中全部Shader的全部variant编译并加入包中
4. Build Assetbundle时,Unity会将关联的Shader的全部由multi_compile定义的variant以及使用到的variant编译并加入包中

Unity5 (5.0-5.2) Shader编译机制初探 - 小心,Shader在吞噬你的内存相关推荐

  1. .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析

    .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析 .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析 作者:&;nbsp来自:网络 htt ...

  2. C++模板编译与C++编译机制在多文件编译时的冲突

    C++模板编译 C++模板编译要编译两次. 以函数模板为例: 第一次编译检查语法 第二次编译生成具体的模板函数 第一次编译发生在正常的编译期间,第二次编译发生在函数模板调用期间. C++编译机制 C+ ...

  3. Vulkan shader编译

    大家好,接下来将为大家介绍Vulkan shader编译. 一.编译shader 在项目根目录下创建一个子目录,名shaders用于存储顶点着色器文件shader.vert和片段着色器文件shader ...

  4. 最新版本Redis:Redis 7.0 安装使用,编译安装Redis,Redis使用场景-2022年最新Redis图解安装

    最新版本Redis:Redis 7.0 安装使用,编译安装Redis,Redis使用场景. 本章主要目标: 1.Redis介绍 2.下载Redis,编译安装Redis 3.启动Redis使用 4.Re ...

  5. MIDP2.0引入了Push注册机制

    Push MIDP2.0引入了Push注册机制,作为一种允许应用被自动启动的方法,由预先设置的警告或者经inbound连接收到的消息. 通过这种方法,MIDlets可以用来设置处理规则事件,如定时从服 ...

  6. 利用mysql的预编译机制_SQL注入笔记记录+MySQL的事务隔离级别

    (一)SQL注入. 1.如何理解SQL注入? SQL注入是一种将SQL代码添加到输入参数中,传递到SQL服务器解析并执行的一种攻击手法. 2.SQL注入是如何产生的? web开发人员无法保证所有的输入 ...

  7. 编译时和运行时、OC中对象的动态编译机制

    编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识别的字 ...

  8. Swift4.0复习特性、编译标志和检查API的可用性

    1.Swift中的特性: @引出,后面紧跟特性名,圆括号带参数即可. @attribute(args) avaiable: 指明对象,函数,类型的可用性. @available(iOS 10.0, m ...

  9. MySQL 8.0.22 源码编译安装全过程

    墨墨导读: Mysql的8.0版本出来已经有一段时间了,近期研究下源码调试.整个编译过程越来越复杂了. 近期研究下源码调试,MySQL5.7版本源码安装还是比较简单的,有很多例子参考.所以这次选择My ...

  10. win10 + bazel-0.20.0 + tensorflow-1.13.1 编译tensorflow GPU版本的C++库

    win10 + bazel-0.20.0 + tensorflow-1.13.1 编译tensorflow GPU版本的C++库 安装所需软件/库 Step1. 安装vs2015,CUDA 10.0和 ...

最新文章

  1. Apache Storm 实时流处理系统通信机制源码分析
  2. 计算机二级ms office知识点讲解,全国计算机二级MSOffice复习知识点
  3. numpy.ceil() 和 numpy.floor()--向上取整和向下取整
  4. 超赞Transformer+CNN=SOTA!
  5. 使用SQL数据库在Python中执行CRUD操作
  6. 微软服务器离线补丁工具包,wsus offline update
  7. 分子排列不同会导致_东华大学《高分子物理》各章选择判断题
  8. springboot全局异常处理_SpringBoot:如何优雅地处理全局异常
  9. Codeforces 208A:Dubstep(字符串)
  10. linux系统支持什么输入法,Linux系统常用输入法框架
  11. TF-IDF算法(原理+python代码实现)
  12. MonoRail学习笔记二:框架代码下载
  13. 利用阿里云主机快速搭建基于wordpress的个人博客网站
  14. 【游戏开发】多人游戏网络同步相关技术(基础原理篇)
  15. 【python句柄获取】——简单明了的获取窗口句柄,并使用句柄操作获取相应内容(全网最详细)
  16. 硬件nat关闭还是开启_SSD4K对齐了,但是速度还是很慢怎么办?我的主板是华硕990FX,AHIC也开了,检测也通过了,-小派4K...
  17. 大三前端doge迟来的春招实习总结(百度offer)
  18. webp格式的图片如何在html中应用
  19. Java多线程【三种实现方法】
  20. Green UML Eclipse插件

热门文章

  1. php读取json三级,php-流明从文件中读取JSON
  2. 《Linux管理与应用》课程考核方案
  3. 用wget命令整站下载
  4. 17行python代码爬取堆糖网所有MeiNv图片
  5. ERD Commander 2005 使用教程
  6. 给SAP初学者的建议!
  7. 某土豪公司很糟糕的面试体验
  8. 嵌入式应该怎么去学?-熊健-专题视频课程
  9. 魔镜mirror安卓版打不开_魔镜Mirror
  10. Revel组件化开发框架