4

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

 1 year ago
source link: https://www.xuanyusong.com/archives/4977
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

专注移动互联网,专注Unity3D游戏开发

动态开关的宏导致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>

一共产生了8种组合,这样就有一个尴尬的事。实际游戏中可能用不到这8种组合,但是由于multi_compile导致必须全部编译,因为有动态开关的需求,也无法使用shader_feature。

比如逻辑上A不会和B进行组合,但会和C进行组合,而且A是运行时可以动态开关的。最终有效的宏组合应该只有5个,如何才能有效的剥离无用的组合呢?

<no keywords defined>

最后通过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游戏开发

留下一个回复 取消回复

你的email不会被公开。

评论

显示名称 *

电子邮箱地址 *

网站地址

在此浏览器中保存我的显示名称、邮箱地址和网站地址,以便下次评论时使用。

返回顶部 网站地图   ©2012-2021 XUANYUSONG.COM 雨松MOMO | Theme frontopen2

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK