今天Profiler了一下发现Shader的内存已经接近1个G了,原因就是multi_compile引起的。其实大部分宏都是采用的shader_feature的方式,但是由于某些效果需要运行时代码动态开关,不得不写成multi_compile,比如我们写了三个宏。
#pragma multi_compile _ A
#pragma multi_compile _ B
#pragma multi_compile _ C
如下图所示,点击Show可以看到具体一共是那些宏的组合。
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个,如何才能有效的剥离无用的组合呢?
<no keywords defined>
C
B
B C
A
A C
最后通过IPreprocessShaders就可以进行宏的剥离。
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程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!


点赞收藏,感谢大佬分享