Shader 加载相关优化

mat 用keyworld shader 会打包
降低 Shader的keyWord 数量,少用fallback
shader warmup 加快编译
Shader.WarmupAllShaders和ShaderVariantCollection.WarmUp两种方式进行预加载,后者耗时更少。
把Shader 都达到AB中,除执行LoadAllAssets操作外,还需要进行Shader.WarmupAllShaders操作,因为在Unity5.x版本中,Shader的解析和CreateGPUProgram操作是分离的。

ShaderVariantCollection loadObject = ABLoader.Instance.LoadAsset(ShaderVariantsCollectionABName, ShaderVariantsCollectionABName);
if (null != loadObject)
{
    loadObject.WarmUp();
}

这里要注意unity 内置的Shader他们加载和释放是不受控制的 下载一份替换掉 或者完全不用。

https://www.duanyiliang.com/2018/11/21/unity/shader_load_performace/

关于shader 热更新

对 各种打包shader 方法进行了分析
Unity中Shader是否可以热更新的测试

使用着色器变体群(ShaderVariantCollection)

ShaderVariantCollection是Unity在5.x后提供的一个着色器预编译的方案,使用它可以轻松的指定需要着色器变体,在需要的时候加载、解析、编译等一条龙服务。
ShaderVariantCollection其实就是一个着色器资源列表,是一个由通道类型+着色器关键字组合的列表。
Unity其实已经自动统计了 在Graphics 中可以设置
下面这篇文章写的很细
https://gameinstitute.qq.com/community/detail/118869
官方文档:https://docs.unity3d.com/ScriptReference/ShaderVariantCollection.html

避免运行编译
会提前编译引擎

shader_feature 和multi_compile 含义?

Unity的Shader中通过multi_compile和shader_feature来定义宏(keyword)。最终编译的时候也是根据这些宏来编译成多种组合形式的Shader源码。其中每一种组合就是这个Uniy Shader的一个Variant。
进行切换的要使用Material.EnableKeyword()和Material.DisableKeyword()来开关对应的宏,然后Unity会根据你设定的组合来匹配响应的shader variant进行渲染
另外Shader.EnableKeyword,和Shader.DisableKeyword是对Shader进行全局宏设置的
multi_compile和shader_feature的区别
1.如果你在shader中添加了
1 #pragma multi_compile _A _B
2 #pragma multi_compile _C _D
  那么无论这些宏是否真的被用到,你的shader都会被Unity编译成四个variant,分别包含了_A _C,_A _D, _B _C,_B _D四种keyword组合的代码

2.如果是
1 #pragma shader_feature _A _B
2 #pragma shader_feature _C _D
  那么你的shader只会保留生成被用到的keyword组合的variant,至于如何判定哪些组合被用到了,等后面提到Assetbundle时候再说。

ShaderVariant与Assetbundle的关系

**1.如果shader没有与使用它的材质打在一个AB中,那么shader_feature的所有宏相关的代码都不会被包含进AB包中(有一种例外,就是当shader_feature _A这种形式的时候是可以的),这个shader最终被程序从AB包中拿出来使用也会是错误的(粉红色).

2.把shader和使用它的材质放到一个AB包中,但是材质中没有保存任何的keyword信息(你在编辑器中也是这种情况),shader_feature会默认的把第一个keyword也就是上面的_A和_C(即每个shader_feature的第一个)作为你的选择。而不会把_A _D,_B _C,_B _D这三种组合的代码编译到AB包中。

3.把shader和使用它的材质放到一个AB包中,并且材质保存了keyword信息(_A _C)为例,那么这个AB包就只包含_A _C的shaderVariant.**
可以看到shader_feature所定义的keyword产生的ShaderVariant并不是全部被打包到AB中,特别是你想在游戏运行时动态的通过EnableKeyWorld函数来进行动态修改材质使用的shaderVariant,如果一开始就没有把对于variant放进AB包,自然也就找不到。

ShaderVariantCollection

为了解决这种问题,Unity5.0以后引入了ShaderVariantCollection(下面简称SVC),这里不讲用法,只说问题,这个SVC文件可以让我指定某个shader要编译都要编译带有哪些keyword的变种。并且在ProjectSetting->Graphics界面新加了一个Preloaded Shaders列表,可以让你把SVC文件放进去,编译时指定的Shader就会按照SVC中的设置进行正确的variant生成,而不会像Always Include Shaders列表中的那样全部变种都生成。

但是它在AB中的表现可就不尽如人意了,要让它起作用,就必须把它和对应的shader放在一个AB中,而且除了5.6以外版本,我试了几个都不能正确使用,不是一个variant都没生成,就是只生成一个shadervariant(和放一个没有设置keyword的材质效果一样).你可以自己用UnityStudio打开查看一下生成的AB内容。

shader catch 有缓存 第二次打开会快

shaderlib 真正的program intshader

shaders 指 序列化shader

shader
key value

你可能感兴趣的:(Shader 加载相关优化)