今天Profiler了一下发现Shader的内存已经接近1个G了,原因就是multi_compile引起的。其实大部分宏都是采用的shader_feature的方式,但是由于某些效果需要运行时代码动态开关,不得不写成multi_compile,比如我们写了三个宏。
1 2 3 4 5 |
#pragma multi_compile _ A #pragma multi_compile _ B #pragma multi_compile _ C |
如下图所示,点击Show可以看到具体一共是那些宏的组合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Keywords always included into build: A B C 8 keyword variants used in scene: <no keywords defined> C B B C A A C A B A B C |
一共产生了8种组合,这样就有一个尴尬的事。实际游戏中可能用不到这8种组合,但是由于multi_compile导致必须全部编译,因为有动态开关的需求,也无法使用shader_feature。
比如逻辑上A不会和B进行组合,但会和C进行组合,而且A是运行时可以动态开关的。最终有效的宏组合应该只有5个,如何才能有效的剥离无用的组合呢?
1 2 3 4 5 6 7 8 |
<no keywords defined> C B B C A A C |
最后通过IPreprocessShaders就可以进行宏的剥离。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using UnityEngine; using UnityEngine.Rendering; class MyCustomBuildProcessor : IPreprocessShaders { ShaderKeyword A = new ShaderKeyword("A"); ShaderKeyword B = new ShaderKeyword("B"); public int callbackOrder { get { return 0; } } public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data) { if ("Unlit/Custom1" != shader.name) { return; } for (int i = data.Count - 1; i >= 0; --i) { //当组合中同时包含A和B的时候剥离这个shader if (data[i].shaderKeywordSet.IsEnabled(A) && data[i].shaderKeywordSet.IsEnabled(B)) { data.RemoveAt(i); } } } } |
这样改完以后内存就小了很多。
- 本文固定链接: https://www.xuanyusong.com/archives/4977
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
点赞收藏,感谢大佬分享