commencer à collectionner
YooAsset.Editor.ShaderVariantCollector.Run
Créer des scènes temporaires
// 创建临时测试场景
CreateTempScene();
_steps = ESteps.Prepare;
EditorApplication.update += EditorUpdate;
Phase de préparation
Reflection appelle ShaderUtil.ClearCurrentShaderVariantCollection pour effacer les variantes collectées par le projet en cours, et nous devons les collecter à nouveau ;
EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "ClearCurrentShaderVariantCollection");
Comment appeler de manière réfléchie
/// <summary>
/// 调用私有的静态方法
/// </summary>
/// <param name="type">类的类型</param>
/// <param name="method">类里要调用的方法名</param>
/// <param name="parameters">调用方法传入的参数</param>
public static object InvokeNonPublicStaticMethod(System.Type type, string method, params object[] parameters)
{
var methodInfo = type.GetMethod(method, BindingFlags.NonPublic | BindingFlags.Static);
if (methodInfo == null)
{
UnityEngine.Debug.LogError($"{
type.FullName} not found method : {
method}");
return null;
}
return methodInfo.Invoke(null, parameters);
}
Collectionne tous les shaders
YooAsset.Editor.ShaderVariantCollector.GetAllMaterials
tous les actifs dépendant du collecteur
// 获取所有打包的资源
CollectResult collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(EBuildMode.DryRunBuild, _packageName);
foreach (var assetInfo in collectResult.CollectAssets)
{
string[] depends = AssetDatabase.GetDependencies(assetInfo.AssetPath, true);
foreach (var dependAsset in depends)
{
if (allAssets.Contains(dependAsset) == false)
allAssets.Add(dependAsset);
}
Collectez tous les shaders qui dépendent de l'actif
List<string> allMaterial = new List<string>(1000);
foreach (var assetPath in allAssets)
{
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Material))
{
allMaterial.Add(assetPath);
}
Collectez les variantes, la caméra illumine tous les shaders une fois
Collection de variantes, ne traitez qu'un maximum de 1000 shaders à chaque fois, s'il dépasse, attendez que le prochain lot soit à nouveau
traité
_allMaterials, puis traiter la gamme actuelle
int count = Mathf.Min(_processMaxNum, _allMaterials.Count);
List<string> range = _allMaterials.GetRange(0, count);
_allMaterials.RemoveRange(0, count);
Créez un ensemble de géométries de sphères dans la scène et organisez-les soigneusement, puis alignez la caméra de rendu sur elles et assurez-vous qu'elles sont toutes visibles ; attribuez
ces ressources matérielles à ces géométries de sphères par lots et effectuez le rendu pendant 100 ms ;
traitement complet
Chemin de collection de variantes YooAsset.Editor.ShaderVariantCollectorSetting.SavePath = "Assets/MyShaderVariants.shadervariants"
appel de réflexion ShaderUtil.SaveCurrentShaderVariantCollection pour enregistrer dans une ressource de collection de variantes globale
EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "SaveCurrentShaderVariantCollection", savePath);
Le fichier de sortie
MyShaderVariants.shadervariants sera empaqueté dans le package unityshaders.bundle
Sortie json, vous pouvez afficher le mot-clé pour faire l'élimination correspondante
AssetPath": "Resources/unity_builtin_extra",
"ShaderName": "Standard",
"ShaderVariantElements": [
{
"PassType": 4,
"Keywords": [
"DIRECTIONAL",
"LIGHTPROBE_SH",
"SHADOWS_SCREEN",
"SHADOWS_SPLIT_SPHERES"
]
},
{
"PassType": 4,
"Keywords": [
"DIRECTIONAL",
"LIGHTPROBE_SH",
"SHADOWS_SCREEN",
"SHADOWS_SPLIT_SPHERES",
"_EMISSION"
]
},
Supprimer l'exemple de code de mot-clé lors de l'emballage
public class StripInstancingOnKeyword : IPreprocessShaders
{
public int callbackOrder
{
//多个回调处理的处理顺序
get {
return 0; }
}
//在执行打包assetbundle会处理
public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> inputData)
{
Debug.Log(string.Format("shader:{0}", shader.name));
//反向遍历,有利于删除
for (int i = inputData.Count - 1; i >= 0; i--)
{
ShaderCompilerData input = inputData[i];
//Global And Local Keyword
if (input.shaderKeywordSet.IsEnabled(new ShaderKeyword("DIRECTIONAL")) ||
input.shaderKeywordSet.IsEnabled(new ShaderKeyword(shader, "DIRECTIONAL")))
{
Debug.Log(string.Format("剔除shader:{0},变体{1}", shader.name, "DIRECTIONAL"));
inputData.RemoveAt(i);
}
}
}
}