unity shader依赖打包,Shader.CreateGpuProgram耗时处理

本系列文章由抗痘洁面泥 出品,转载请注明出处。 


1:项目中的shader应该如何进行打包

        做游戏开发的都知道shader是游戏中必不可少的一种资源,如果没有shader就无法创造出炫酷的特效,也没有真实的人物表现。而在Unity里面shader是需要附加到Material上才能发挥作用的,而使用Unity的手游开发者基本上回选择AssetBundle这种资源的组合形式,AssetBundle是使用的依赖进行打包,这样的话就会导致项目中每个材质引用到的shader都会打包到材质对应的AssetBundle中(如果shader没有被单独打包的话)这样会造成材质球包体过大,我简单的做了下测试,直接创建一个Material使用的Mobile/Diffuse,并不包含任何贴图的情况下打包,包体大小是31KB,如果把Mobile/Diffuse单独打包,包体是2KB。这样会造成游戏包体过大,内存过高,而且每次加载需要加载额外的东西的耗时也会很高,我参与的项目就遇到这种情况,造成了很严重的资源冗余,所以我就想把Shader单独出来打成一个包。很多人会很疑惑不是官网上说的不是把Shader包含进Always Include不就可以了?这样就不会造成冗余了,这种是只针对的是Unity自带的一些Shader,而我们自己写的一些常用的Shader,只要被引用了如不单独打包还是会造成冗余的。当我们把Shader打包之后我们就不能使用Shader.Find找到我们想要的Shader了,因为Shader.Find是只能查找到直接被build进APP的Shader有效,也就是放在Resource目录下的和Always Inlude里面包含的。既然打成了AssetBundle就只能使用assetbundle.LoadAsset来进行加载了。

2:对于Always Include Shader及ShaderVariant的使用

        always include是Editor下的一个设置,这个设置可以让你不用去关心你的shader是怎么打包的,反正你只需要把shader拖上去,你就可以在代码中使用shader.find()找到这个shader,就像刚接触Unity时什么都放在Resources目录下使用Resources.Load()一样方便,但是always include 会把所有的shader变体都包含进去,而不止是你使用的,所以说如果你把Standard.Shader包含进去的话你会发现你的shaderlab这一项消耗的内存会异常的高。而Unity也使用了另外的一种方式,就是使用ShaderVariantCollection,这个操作是可以把使用到的变体收集起来和Shader打一个包,然后在游戏启动的时候优先加载Shader达到和always include一样的效果。

3:减少Shader.CreateGpuProgram的耗时

        给项目做过优化的童鞋应该都对Shader.parse和Shader.CreateGpuPrograsm这两个接口不会太陌生,这两个接口我们在使用Profiler查看的时候可以经常看到二者的耗时。其中shader.parse主要是在加载shader,可以理解为Resources.Load/AssetBundle.LoadAsset,而CreateGpuProgram则是去通知Gpu,有新的Shader加载进来了,需要GPU对这个Shader针对目标平台进行编译,也可以理解为GPU自己需要对Shader进行一次处理,不然GPU也不知道要如何渲染目标物体,Shader.Parse的耗时可以使用always include或者使用AB包并常驻内存不去卸载,来解决,而CreateGPUProgram则可以使用在游戏初始化的时候使用例如一个Cube挂上相应的Material然后放到视域体内渲染一帧即可,然后把Cube移动到很远的地方就可以了,由于Shader已经常驻内存,并不会去卸载,所以GPU也无需多次编译Shader,以达到减少消耗的目的。或者使用ShaderVariantCollection.WarmUp,这个会自动创建三角面来告知GPU编译这个shader了,但是这个接口会造成启动的时候耗时较高,而且如果当shader被卸载,再加载的时候还是会出现CreateGPUProgram的。

        最近一直在对项目进行优化,后面会出一篇有关项目资源管理的博客,谈谈自己对项目管理的一点见解,自己的项目的资源等个方便可以用龙蛇混杂来形容,也没有专门的人去管理和维护,真是什么样的资源都有。心累。

猜你喜欢

转载自blog.csdn.net/tc3819171/article/details/79684386