unity3d:YooAsset shader变体收集代码解析

news2024/12/22 19:40:32

开始收集

YooAsset.Editor.ShaderVariantCollector.Run

创建临时场景

// 创建临时测试场景
			CreateTempScene();

			_steps = ESteps.Prepare;
			EditorApplication.update += EditorUpdate;

准备阶段

反射调用ShaderUtil.ClearCurrentShaderVariantCollection清空当前项目搜集到的变体,我们需要重新搜集一次;

EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "ClearCurrentShaderVariantCollection");

如何反射调用

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

收集全部材质球

YooAsset.Editor.ShaderVariantCollector.GetAllMaterials
所有收集器的依赖asset

// 获取所有打包的资源
			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);
				}

收集所有依赖asset的材质球

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

收集变体,摄像机照射所有材质球一遍

变体收集,每次只处理最大1000个材质球,超过的,等下一批再处理
YooAsset.Editor.ShaderVariantCollectorSetting.ProcessCapacity = 1000
每次处理一批时,总材质球列表_allMaterials去掉0-count,然后处理当前的range

int count = Mathf.Min(_processMaxNum, _allMaterials.Count);
				List<string> range = _allMaterials.GetRange(0, count);
				_allMaterials.RemoveRange(0, count);

在场景中创建一堆sphere几何体,并排列整齐,然后把渲染相机对齐它们,并保证它们都可以看见;
分批次把这些材质资源赋予这些sphere几何体,渲染100ms;
在这里插入图片描述

完成处理

变体收集到路径YooAsset.Editor.ShaderVariantCollectorSetting.SavePath = “Assets/MyShaderVariants.shadervariants”
反射调用ShaderUtil.SaveCurrentShaderVariantCollection保存到一个整体变体集合资源中去

EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "SaveCurrentShaderVariantCollection", savePath);

输出文件
MyShaderVariants.shadervariants会打包进入unityshaders.bundle包里
在这里插入图片描述

输出json,可以查看keyword做相应的剔除

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"
                    ]
                },

打包时去掉keyword代码示例

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第52步 深度学习图像识别:Transformer in Transformer建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;Transformer in Transformer Transformer in Transformer&#xff08;TNT&#xff09;模型是一种新的图像分类模型&#xff0c;由研究者在2021年提出。这种模型的特点是在传统的Vision Transformer模型的基础…

FreeRTOS源码分析-1创建任务

目录 1 任务的句柄&#xff08;结构体&#xff09; 2 创建任务主要工作 2.1 创建任务初始化源码分析 2.2 任务添加到就绪列表源码分析 2.3任务堆栈的初始化源码分析 问&#xff1a;R0为什么要入栈保存&#xff1f;因为作为函数的第一个传入参数&#xff0c;必须也要保存。…

spring复习:(37)ProxyFactoryBean之getObject

该工厂bean的getObject代码如下&#xff1a; public Object getObject() throws BeansException {initializeAdvisorChain();if (isSingleton()) {return getSingletonInstance();}else {if (this.targetName null) {logger.info("Using non-singleton proxies with sing…

4.CSS图文样式

考点&#xff1a;line-height为200%时&#xff0c;font-size为40px

第十五章:DenseASPP for Semantic Segmentation in Street Scenes——在街景语义分割中的DenseASPP

0.摘要 语义图像分割是自动驾驶中的基本街景理解任务&#xff0c;在这个任务中&#xff0c;高分辨率图像中的每个像素被归类为一组语义标签。与其他场景不同&#xff0c;自动驾驶场景中的物体呈现出非常大的尺度变化&#xff0c;这给高级特征表示带来了巨大挑战&#xff0c;因为…

IDEA设置显示行号和方法间的分隔符

IDEA设置显示行号和方法间的分隔符 选择File--Settings--Edotor-General-Apperance&#xff0c;勾选上下图中的选项后点击 OK 即可。 每个函数不迷路~~ Show line numbers&#xff1a;显示行数 Show method separators&#xff1a; 显示方法分隔线。

央视赋能,强势出击——方圆出海与《品牌中国》栏目达成战略合作

2023 央视赋能&#xff0c;强势出击 方圆出海 “日前&#xff0c;深圳市方圆出海科技有限公司与《品牌中国》栏目携手&#xff0c;双方正式达成战略合作协议&#xff0c;央视《品牌中国》栏目负责人正式授予方圆出海“《品牌中国》重点推荐品牌”的荣誉称号。 此次签约标志着…

js的this绑定规则以及箭头函数

目录 调用位置默认绑定隐式绑定隐式丢失 显式绑定callapplybind new绑定装箱绑定优先级this规则之外忽略显式绑定间接函数引用 箭头函数 调用位置 从字面意思上来理解&#xff0c;this似乎是指向自己的 然而在JavaScript中&#xff0c;this并不是绑定到自身的 可以看这一个例子…

蓝牙HID模式下输出中文原理简介

目录 前言一、蓝牙和HID简介二、Unicode编码简介三、Windows下alt键code编码输出中文四、蓝牙HID模式下实现在手机上输入中文的原理 前言 最近在使用蓝牙模组&#xff0c;对于蓝牙模组如何输出中文的原理不太清楚&#xff0c;所以找了一些资料简单学习了下&#xff0c;总结如下…

目标检测——FasterRCNN原理与实现

目录 网络工作流程数据加载模型加载模型预测过程RPN获取候选区域FastRCNN进行目标检测 模型结构详解backboneRPN网络anchorsRPN分类RPN回归Proposal层 ROIPooling目标分类与回归 FasterRCNN的训练RPN网络的训练正负样本标记RPN网络的损失函数训练过程实现正负样本设置损失函数 …

Kubernetes 使用 helm 部署 NFS Provisioner

文章目录 1. 介绍2. 预备条件3. 部署 nfs4. 部署 NFS subdir external provisioner4.1 集群配置 containerd 代理4.2 配置代理堡垒机通过 kubeconfig 部署 1. 介绍 NFS subdir external provisioner 使用现有且已配置的NFS 服务器来支持通过持久卷声明动态配置 Kubernetes 持久…

大模型基础知识汇总

本文总结大模型相关基础知识&#xff0c;用于大模型学习入门 &#xff08;持续更新中…&#xff09; 文章目录 NLP 基础知识传统 NLP 知识NLU 与 NLG 各种任务的差异 Transformer 相关知识Pre Norm与Post Norm的区别&#xff1f;Bert 预训练过程手写 transformer 的 attention …

从0到1:跑团小程序开发心得笔记

背景介绍 随着健康意识的兴起&#xff0c;越来越多的人选择加入跑步俱乐部&#xff0c;不仅体验到了运动的乐趣&#xff0c;也感受到了人生的不同色&#xff0c;那么通过小程序&#xff0c;把俱乐部搬到手机上&#xff0c;通过小程序了解俱乐部动态和运动常识&#xff0c;可以…

C++自定义信号和QML的槽函数建立连接

0x00 在C代码在定义一个信号函数&#xff1a;“void sendData2UI(QString msg);”&#xff0c;该函数主要是将接收到的UDP消息发送到QML界面中 #ifndef UDPCLI_H #define UDPCLI_H#include <QObject> #include <QUdpSocket> #include <QString>class UdpCli …

【Netty】NIO基础(三大组件)

文章目录 三大组件Channel & BufferSelector ByteBufferByteBuffer 正确使用姿势ByteBuffer 内部结构ByteBuffer 常见方法分配空间向 buffer 写入数据从 buffer 读取数据mark 和 reset 字符串与 ByteBuffer 互转Scattering ReadsGathering Writes粘包、半包分析 附&#xf…

《啊哈算法》第一章--排序

文章目录 前言一、排序算法二、桶排序三、冒泡排序三、快速排序总结 前言 今年蓝桥杯没有拿到省一&#xff0c;所以就决定沉下心来学习算法&#xff0c;为了使得算法的学习更加稳固&#xff0c;所以就拿起了&#xff0c;最基础的且最经典的一本算法书《啊哈算法》&#xff0c;…

Redis进阶底层原理- 持久化

Redis作为基于内存的缓存数据库&#xff0c;就会存在断电即失的问题&#xff0c;所以数据的持久化是非常重要的。Redis随着版本升级迭代&#xff0c;持久化技术也在不断的升级&#xff0c;&#xff08;从最开始的RDB&#xff0c;到的Redis1.1版本加入AOF&#xff0c;3.0版本支持…

全志F1C200S嵌入式驱动开发(sd卡驱动)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 说是sd卡,其实是micro sd卡,或者称之为tf卡更合适。一般的soc都支持从tf卡启动,所以用tf卡来学习soc、驱动和linux,对新人来说是比较合适的。前面我们已经用sd卡构建了一个类似…

uniapp:针对与富文本解析的几种方法

第一章、富文本的解析方法 1.1 uniapp自带组件&#xff1a;rich-text <rich-text :nodes"nodes"></rich-text> 1.2 v-html <view v-html"item.content"></view> 1.3 uview组件&#xff1a;u-parse <u-parse :content&quo…

学习babylon.js --- [3] 开启https

babylonjs提供WebVR功能&#xff0c;但是使用这个功能得用https&#xff0c;本文讲述如何使用自签名证书来开启https&#xff0c;基于第二篇文章中搭建的工程。 一 生成自签名证书 首先要安装openssl&#xff0c;这个去网上搜下就行了。安装完之后在终端下输入openssl回车可以…