文章目录
unity验证shader变化对材质ab的影响
项目发现 shader 变化时,引用该 shader 的材质打出来的ab,存在没有变化的情况
需要验证的问题如下:
- AssetDatabase.reflesh/reimport all/save asset 对本地 mat 文件的影响
- assetbundle cache 的有无对 mat ab 的影响
- 修改四个方面观察影响:
-
- 在 shader property 的中间新增一个 property
-
- 在 shader property 的末尾新增一个 property
-
- 修改函数体内容
-
- 新增/删除函数
以下内容涉及包体 addressable 1.20.3 和 sbp 1.20.2
初探 shader 变化对 material ab 的影响
首先先理一下 shader 到 mat ab 的逻辑:
- mat 引用了 shader 后,会保留与该 shader 的差异值,那些没有产生差异的属性则不会保留
- shader 和 mat 在资产管线中,存在项目源文件和 Library/Artfacts 下的缓存文件两种文件
- 在构建ab中,除了构建出来的 ab,还有 sbp 做的 ab cache
这样就分成区分成 资产管线 和 构建ab 两个方面分别检查问题所在,也有可能是两个方面都有问题
测试流程
- 先准备 origin 资源,即准备好 shadar 和 引用该shader 的 mat,然后打 ab,备份源文件和缓存文件,ab 和 ab cache
- 然后给 shader 中间添加 property,Refresh,打 ab,继续备份,得到以下表格
shaderProperty中间新增property | shader更新 | Artfacts中shader更新 | mat更新 | Artfacts中mat更新 | use_cached_matab_ab更新 | forceRebuild_matab更新 |
---|---|---|---|---|---|---|
Refresh | T | T | F | F | F | T |
shader 变化但是 mat 没有更新,这点跟 TA 大佬确认过了,表示这种情况很常见,这里可以推理出因为 mat 没有更新,所以导致 mat ab 没有更新。这看起来是资产管线的问题,但是理解上,如果 mat 只保留差异值的话,那么资产管线是没问题的
- Refresh 产生的差异如下
-
- shader ab 解析出来的信息,propInfo 中间新增了属性,propInfo 的顺序与 .shader 文件中的 Properties 一一对应
-
- 获取ab cache信息,发现 shader 和 mat 资产都没有使用ab cache的信息,而是用的最新的资产信息,但是最后出来的 mat ab 没有发生变化
shader 添加的属性命名有 foo,foo1,然后检查构建ab,配置上选择使用缓存,然后修改 shader
- mat 文件对应的ab cache发生了变化!
- 然后每次构建前都手动删掉 mat/shader ab cache,发现 mat ab 并没有更新
意思就是,shader 变化时,构建时没有使用缓存,而是重新检索原资产的信息。到这里,构建ab 这块看起来没有问题,整理一下以上的信息:
- 构建ab 时,拿到的是最新的 mat/shader 信息,asset 的 ab cache没有问题
然后forceRebuild,再还原修改,添加修改 foo2,进行 reimport all,此时资产应该是全部刷新过了,然后再打 ab,结果发现 mat ab 还是没有更新。然后还原修改,再打 ab,突然发现 foo,foo1 信息段出现了!
mat ab 不更新的原因
foo,foo1 信息段出现为什么很奇怪?因为foo,foo1 是在 reimport all 之前设置的,在 reimport all 之后,和资产本身相关的信息应该都是刷新了的,但是它又出现了,那么这个 foo,foo1 信息段保存在哪里没有被清空呢?只有 ab cache 了!
然后细查 ab cache,发现 cache 分成三个部分,分布在三个 task 中:
- asset cache,在 CalculateAssetDependencyData.RunInternal()
- assetbundle cache,在 TaskCachingUtility.RunCachedOperation(),由 WriteSerializedFiles.Run() 触发
-
- WriteSerializedFiles.ProcessUncached() 中,uncached ab 会调用 AssetBundleWriteOperation.Write(),这里直接调用 unity 接口 ContentBuildInterface.WriteSerializedFile() 创建 CAB 缓存文件
-
- WriteSerializedFiles 中有一个重要变量是 m_WriteData.Command,该变量是在另一个 task 中构建的,即 GenerateBundleCommands.CreateAssetBundleCommand(),debug 可以去查相关逻辑
- bundle archive cache, 在 ArchiveAndCompressBundles.Run()
之前检查的 cache 只有第一部分,所以一直找不到问题!可以发现修改 shader,有关 mat 的 asset cache 也会被刷新,这里没有问题,问题在 assetbundle cache 上,沿用的旧的 cache,导致出来的 mat ab 没有刷新,这一点通过手动删除指定 cache 可以证明