Shader变种收集PassType的问题
source link: https://www.xuanyusong.com/archives/5027
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变种收集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 #pragma multi_feature _ A 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下的宏都能找出来了。
有了以上信息就可以带入passtype来生成着色器变种了。 以上代码在Unity2022.1中跑通。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK