首页 >Unity3D频道 >【Unity3D研究院之游戏开发】 > Shader变种收集PassType的问题
2023
05-13

Shader变种收集PassType的问题

材质上可以通过material.shaderKeywords来获取使用到的宏,接着使用ShaderVariantCollection就可以动态创建变种收集器了。

ShaderVariantCollection shaderVariantCollection = new ShaderVariantCollection();
shaderVariantCollection.Add(new ShaderVariantCollection.ShaderVariant(shader, /*passtype*/, keyword));
AssetDatabase.CreateAsset(shaderVariantCollection, collectionPath);

这里面有个巨大的坑就是passtype,比如这里有两个宏A和B同时开启时,因为他俩在不同的LightMode中,所以对应的passType是不同的。

SubShader
{
    Pass
    {
        #pragma multi_feature _ A
    }

    Pass
    {

        Tags{"LightMode" = "ShadowCaster"}
        #pragma multi_feature _ B
    }
}

上个项目我就没有彻底解决它, 今天决定仔细研究研究。我们需要获取每个Pass中定义的宏,以及它们的passType,最终发现还是反射大法好。 核心方法就是通过反射设置每个PassIdentifier在调用shader.FindPassTagValue获取每个Pass设置的LightMode的名称,在通过ShaderUtil.GetPassKeywords获取每个Pass中定义的宏。

for (int i = 0; i < shader.passCount; i++)
{
    string shaderTag = shader.FindPassTagValue(i, new ShaderTagId("LightMode")).name;
    PassIdentifier identifier = new PassIdentifier();
    Type myType = typeof(PassIdentifier);

    FieldInfo myFieldInfo = myType.GetField("m_PassIndex", BindingFlags.NonPublic | BindingFlags.Instance);
    object asObject = identifier;
    myFieldInfo.SetValue(asObject, (uint)i);
    identifier = (PassIdentifier)asObject;

    Debug.Log(shaderTag); //LightMode 名称 


    List<string> keyword = new List<string>();
    foreach (var item in ShaderUtil.GetPassKeywords(shader, identifier))
    {
        if(item.type== ShaderKeywordType.UserDefined)
        {
            keyword.Add(item.name);
        }
    }
    //输出LightMode定义的宏
    Debug.Log(string.Join(",", keyword.ToArray()));
}

这里我用URP自带的Lit Shader输出的,可以发现每个Pass下的宏都能找出来了。

Shader变种收集PassType的问题 - 雨松MOMO程序研究院 - 1

有了以上信息就可以带入passtype来生成着色器变种了。 以上代码在Unity2022.1中跑通。

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

Shader变种收集PassType的问题》有 2 条评论

  1. visitor 59说:

    大哥了,人家分享知识你感谢还来不及呢,更没有义务回复你,还“我也不会见怪的”

  2. Nynka说:

    虽然你是专精unity的,但是我抱着试试看的态度还是想问一下,你对ue的项目转移到unity上有什么好的见解么?当然不回答我也不会见怪的

留下一个回复

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