关于rendering:Shader打AssetBundle包变体丢失问题

9次阅读

共计 4374 个字符,预计需要花费 11 分钟才能阅读完成。

1)Shader 打 AssetBundle 包变体失落问题
​2)Unity 降级后在 iOS 平台的贴图导入问题
3)字体文件 AssetBundle 包解体
4)给主相机设置 RT 的注意事项
5)FBX 的导入 WeldVertices 的设置问题


这是第 271 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。

UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)

AssetBundle

Q:Unity 官网后处理 PostProcessing,进行 AssetBundle 打包时,变体太多(4000+),批改了 uber.shader,屏蔽了我的项目中不可能应用的关键字(前期要应用也能够通过热更批改)。

AssetBundle 打包后,发现变体没齐全打包,Editor 下查看 Shader 变体数量是 300+,打包后应用 AssetStudio 查看 AssetBundle,发现只打了 100+ 的变体,大部分失落。运行通过断点调试也验证了所有 Key 均设置,FrameDebug 中也失落了一些关键字。

uber.shader 下所有关键字均是 multi_compile 定义,实践上 multi_compile 定义的关键字都会全编译所有组合,然而打包后呈现失落。

A:在进行单元测试中,在一个空我的项目中打包 uber.shader,发现打包后,变体正确。然而开发我的项目和打包我的项目仍旧生成不正确。狐疑是 Unity 缓存起因。于是删除 Library 目录下 shaderCache,再次打包,还是不正确。再次删除已生成的 AssetBundle 资源,齐全从新生成,终于正确。

所以 multi_compile 定义的关键字打包呈现问题,须要删除缓存和已生成的 AssetBundle 能力最终正确生成新的 AssetBundle。

感激题主 1 9 7 3-311135@UWA 问答社区提供了答复

Asset

Q:咱们始终用贴图后处理脚本对贴图进行导入,在 iOS 平台应用 ASTC_6x6 格局。然而降级到 Unity 2019,关上 iOS 工程,经同步缓存和导入实现后,大部分贴图的预览界面上并没有显示压缩格局和压缩后的尺寸,而是显示 no yet compressed,仿佛导入操作没有实现。Android 平台并没出问题。

这样的贴图会显示含糊,并且打出的 Bundle 还会更大。手动 Reimport 能够解决。然而如果另外建设一份工程拷贝,则又会呈现同样的问题。求问有什么解决办法?

A1:经查,是我这边的纹理资源导入后处理脚本(iOS)有问题,然而其在 Unity 2018 下不会体现进去,然而在 Unity 2019 中会间接让某些贴图的导入工作无奈实现。因为应用了 Unity Accelerator(也就是 Asset Pipeline v2 对应的缓存服务器),从新导入也不会生成新的缓存,只能让进行从新导入的我的项目部分失常。

咱们的导入后处理脚本中在 iOS 下,对 JPG 独自应用了不带通明通道的 ATSC 压缩。在 Unity 2019 中,ATSC 压缩不再辨别是否带通明通道。批改脚本 + 删除 Unity Accelerator 缓存 + 从新导入某个 Working copy(同时也重建了缓存)可解决。

留神:上述无奈导入实现的状况,打出包来会有两个显著的问题:包体变大、图片含糊。

感激题主加菲教主 @UWA 问答社区提供了答复

AssetBundle

Q:AssetBundle 打包参数 BuildAssetBundleOptions.DisableWriteTypeTree。会极大缩减 AssetBundle 包大小,同时也带来运行时 SerializaFile 雷同数量级下内存占用缩减一半左右,并进步加载速度。

官网阐明比较简单:如果开启 DisableWriteTypeTree 选项,则可能造成 AssetBundle 对 Unity 版本的兼容问题。基于其带来的运行时劣势,还是决定应用该选项。

导出测试包所有运行失常,热更新也运行失常,原本认为该优化就完结。然而起初发现雷同的 AssetBundle 资源,在编辑器下 AssetBundle 运行会解体(必然呈现),导出的测试包(所有平台)一切正常。(该问题必须要解决,因为游戏公布后线上的问题能够在本地调试复现,如果本地不能运行 AssetBundle 包或者运行不同的 AssetBundle 包原则上不容许。)

A: 开始排查问题: 首先定位到解体的资源,是 TMPTextPro 相干的字体资源包(复合包,蕴含了多个资源内容)。

验证 BuildAssetBundleOptions.DisableWriteTypeTree 的影响,屏蔽 BuildAssetBundleOptions.DisableWriteTypeTree 打包参数。打包后编辑器运行不解体,必定了该参数造成的问题。(这里过后猜想是 Unity 外部代码的某个宏导致的,导致了在 Editor 下和公布时走了不同的解析代码,然而又没有源代码,无奈具体验证。)

开始排除问题:
首先排除 Unity 的编辑器缓存造成的该问题,重置后仍旧解体。

开始拆解问题包,将所有资源内容单个打包(一个资源对应一个包)。最初精确定位到是 TMPTextPro 的字体 FontAsset 资源包调用 AssetBundle.LoadAsset() 办法时解体。

剖析问题: 设置 DisableWriteTypeTree 参数将不在 AssetBundle 中蕴含相干的文件 TypeTree 信息,是因为没有该信息后导致的反序列化不正确,为什么其它资源能失常解析,就单单 FontAsset 会呈现问题?关上 TMP_FontAsset.cs 源码,查看发现这么一段代码。

#if UNITY_EDITOR
///


/// Persistent reference to the source font file maintained in the editor.
///

[SerializeField]
internal Font m_SourceFontFile_EditorRef;
#endif

发现它竟然在可序列化类中退出了条件编译,造成导出运行和编辑器运行该类的实现不一样。

这就是为什么导出包运行正确,编辑器解体的起因。因为 AssetBundle 打包时的 UNITY_EDITOR 是不成立的,会设置对应平台的宏。所以打包时 FontAsset 资源的数据是不蕴含 m_SourceFontFile_EditorRef 该属性的序列化信息,未开启 DisableWriteTypeTree 时,因为有 TypeTree 信息,编辑下运行程序能通过 TypeTree 信息正确反序列化,当设置 DisableWriteTypeTree 时,反序列化失败,间接解体。

解决: 给属性 m_SourceFontFile_EditorRef 增加标签[NonSerialized],再对应批改一些 Editor 代码,让性能在 Editor 下也正确。

感激题主 1 9 7 3-311135@UWA 问答社区提供了答复

Rendering

Q:用 setTargetBuffers 办法将一张低分辨率 RT 设置给主相机。在屏幕分辨率不变的状况下,对场景相机做了降级。而后呈现了一个问题是:所有的后处理都生效了,查看后发现所有 OnRenderImage 办法的 Source 都为 null(我了解为没有设置 Rendertarget,默认为屏幕)。我将下面那张 FrameBuffer 强行代替 Source 传入后处理,查看 FramedeBugger,后处理几个 Draw Call 能失常渲染,然而仍旧不能对最终成果失效,也就说没有写入到下面的 FrameBuffer。

我之前的解决办法是魔改所有 OnRenderImage,传入 FrameBuffer 代替 Source,输入到另外一张 FinalBuffer,最初再绑定到屏幕上,上面是测试代码。


但我的项目中后处理比拟多,且 ImageBuffer 仍存在后处理中,无端减少了 RenderTexture 的开销。

当初的解决办法是间接设置 TargetTexture,但逻辑操作上会绕一层。想问下引起下面的起因,或者说有什么更好的解决办法?

环境是 2019.4.3f + built-in + OpengES3.0,而后再用 CommandBuffer 将低分辨率适配到高分辨率。

A1:实际下来,倡议还是用 CommandBuffer 来操作,比拟灵便:

  1. OnPreRender 阶段先设置好 TargetBuffer(ColorBuffer:RTA、DepthBuffer:RTB)。
  2. 应用 CommandBuffer 在 CameraEvent.BeforeImageEffects 或者 AfterImageEffects 这个事件上做所有的后处理。
  3. 外围在于第一次 Blit 的 Source 为 ColorBuffer,最初一次 Blit 的 Destination 为 BuiltinRenderTextureType.CameraTarget,两头能够交叉任何后处理成果。

而且如果发现改了 ColorBuffer 的分辨率,画面没有失常缩放,须要第二步后处理的 CameraEvent 改为 AfterEverything:

还有就是如果改了 TargetBuffer,须要对 SceneCamera 做非凡解决。

感激范世青 @UWA 问答社区提供了答复

A2:下图是这两种办法的试验比照,至于两者区别的根本原因,是其办法外部实现的差别:SetTargetBuffers 的实现过程是没有设置渲染指标(也就是屏幕)的 RenderTexture 的,这也就是为何用该办法时 OnRenderImage 中的 Source 是 null。

该问答由 UWA 提供

Asset

Q:问下在 FBX 的导入设置外面,weldVertices 是须要设置为 True 还是 False?

A:倡议设置为 True。雷同顶点会被合并,能够缩小内存和 Mesh 渲染的压力。

感激萧小俊 @UWA 问答社区提供了答复

20211018
更多精彩问题等你答复~

  1. Unity 增量打包 AssetBundle 没变动的资源也会被从新打包
  2. 在模型有 UV2 的状况下开启 Generate Lightmap UVs
  3. 如何实现 AAB 包的增量更新

封面图来源于网络


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)

正文完
 0