首页 >Unity3D频道 >【Unity2D研究院之游戏开发】 > 动态开关的宏导致Shader内存过大
2022
06-11

动态开关的宏导致Shader内存过大

今天Profiler了一下发现Shader的内存已经接近1个G了,原因就是multi_compile引起的。其实大部分宏都是采用的shader_feature的方式,但是由于某些效果需要运行时代码动态开关,不得不写成multi_compile,比如我们写了三个宏。

#pragma multi_compile _ A
#pragma multi_compile _ B 
#pragma multi_compile _ C

如下图所示,点击Show可以看到具体一共是那些宏的组合。

动态开关的宏导致Shader内存过大 - 雨松MOMO程序研究院 - 1

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);
            }
        }
    }
}

这样改完以后内存就小了很多。

 

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

动态开关的宏导致Shader内存过大》有 1 条评论

  1. 星光白云说:

    点赞收藏,感谢大佬分享

留下一个回复

你的email不会被公开。 必填项已用 * 标注。