当前位置: 首页 > news >正文

Unity引擎材质球残留贴图引用的处理

  大家好,我是阿赵。
  这次来分享一下Unity引擎材质球残留贴图引用的处理

一、 问题

  在使用Unity调整美术效果的时候,我们很经常会有这样的操作,比如:

1、 同一个材质球切换不同的Shader、

比如我现在有2个Shader,其中第一个Shader的参数是这样的:

    Properties{_MainTex ("MainTex", 2D) = "white" {}_MaskTex("MaskTex",2D) = "black" {}_floatVal("FloatVal",float) = 1_rangeVal("RangeVal",Range(0,1)) = 1_vecVal ("VectorVal",Vector) = (1,1,1,1)_colVal ("ColorVal",Color) = (1,1,1,1)}

而第二个Shader的参数是这样的:

    Properties{_MainTex ("MainTex", 2D) = "white" {}_specTex("SpecTex",2D) = "black" {}_floatVal("FloatVal",float) = 1_rangeVal("RangeVal",Range(0,1)) = 1_vecVal ("VectorVal",Vector) = (1,1,1,1)_colVal ("ColorVal",Color) = (1,1,1,1)}

  可以看出,它们两个的参数几乎一样,区别只是在一张贴图的名称不同。
  假如先在材质球里选第一个Shader,并且把两个贴图的赋上,现在材质球是这样:
在这里插入图片描述

  然后在这个材质球里面,把Shader改成第二个Shader,会变成这样:
在这里插入图片描述

  很明显,第二张贴图由于名字不一样,所以这个Shader上不会显示之前的那张贴图。
  这时候疑问来了,换了Shader之后,之前的贴图通道里面的引用,是不是就不用管了呢?
在这里插入图片描述

  这时候,可以打开Debug来看这个材质球的参数:
在这里插入图片描述

  可以看到,刚才使用在上一个Shader里面的贴图_MaskTex,其实还是保存在引用里面的。这说明一个问题,假如我们给一个材质球替换Shader,其实上一个Shader使用而当前Shader没有使用的字段参数,都保存在材质球的引用里面。如果我们继续使用这个材质球,那么打包资源的时候很可能就会带着一张我们根本没有用到的贴图。

2、 同一个Shader修改参数的名称

还是拿第一个Shader作为例子:

    Properties{_MainTex ("MainTex", 2D) = "white" {}_MaskTex("MaskTex",2D) = "black" {}_floatVal("FloatVal",float) = 1_rangeVal("RangeVal",Range(0,1)) = 1_vecVal ("VectorVal",Vector) = (1,1,1,1)_colVal ("ColorVal",Color) = (1,1,1,1)}

在这里插入图片描述

  还是把上面的2张贴图都赋上。

  这时候,假如我修改一下其中一张贴图的变量名
Properties{_MainTex ("MainTex", 2D) = "white" {}_MaskTex2("MaskTex",2D) = "black" {}_floatVal("FloatVal",float) = 1_rangeVal("RangeVal",Range(0,1)) = 1_vecVal ("VectorVal",Vector) = (1,1,1,1)_colVal ("ColorVal",Color) = (1,1,1,1)}

  我把_MaskTex改成了_MaskTex2。
在这里插入图片描述

  这个时候,会发现之前赋予的_MaskTex贴图消失不见了。
  这时候问题又来了。是不是修改了Shader里面的变量声明,那么之前声明的变量引用的贴图就消失了呢?
  同样的打开Debug模式看:
在这里插入图片描述

  虽然新增了_MaskTex2的保存项,但实际上原来的_MaskTex贴图还是存在的,引用的贴图也依然存在。所以同样的道理,如果这个时候我们继续使用这个材质球,那么打包的时候,就会包含了一张我们已经不用了的贴图。
  通过上面2个例子可以说明,其实材质球上面已经保存过的参数,不论材质球当前的Shader是否有声明变量,都会在Saved Properties里面一直存在着。但如果不用Debug模式去观察,可能很多使用Unity的朋友都不知道这个问题的存在。这可以说是Unity引擎设计上的一个缺陷。一般使用Unity进行美术资源编辑的,都是美工同事们,他们一般都不会去使用Debug模式,而正常模式下的材质球属性显示里面又没有任何的提示,所以虽然包含了多余的美术资源,但他们是很难发现的。

二、 解决问题。

  如果我们通过材质球的Reset选项去清空材质球的所有参数
在这里插入图片描述

  当然是可以把不用的贴图给清理掉。但那样做的话,会顺便把其他我们正常使用的属性也清理掉了。这显然不是我们想要达到的目的。
  我们的目的很简单,就是保留现在的Shader用到的参数,去掉已经不需要的参数。Unity似乎没有直接提供这样的手段,起码阿赵我没有找到。不过我们可以通过另外一种迂回一点的手段,去实现这个目的。
思路是这样的:
1、 获得材质球当前使用的Shader的所有属性名称
通过

ShaderUtil.GetPropertyCount(shader);

可以获得当前Shader声明的变量个数
2、 使用当前Shader创建一个新的临时材质球

Material newMat = new Material(shader);

3、 通过遍历所有属性名称,从旧的材质球上面获取对应的变量参数,然后赋予给新的临时材质球。
由于不同的变量需要用不同的方法获取和赋值,所以需要知道每一个变量的类型,通过

ShaderUtil.ShaderPropertyType propType = ShaderUtil.GetPropertyType(shader,i);

  可以获得变量类型
在这里插入图片描述

  类型只有5种,所以根据类型分别去操作就行了。Range和Float其实是一样的,用GetFloat和SetFloat方法获取就行。

4、 通过复制材质球属性,把临时材质球的所有属性赋予给原来的材质球。
通过方法:

mat.CopyPropertiesFromMaterial(newMat);

可以把临时材质球的所有属性复制给原来的材质球。
5、 最后保存一下原来的材质球

  通过这些手段之后,目的达到了,不使用的变量被清空,需要的变量保留下来。
在这里插入图片描述

  通过这个思路,可以写一个批处理的工具,批量清理材质球。

三、 源码

  根据自己的情况,写一个UnityEditor的工具,然后遍历需要的材质球,传入方法:

private void CleanUnusedProp(Material mat)
{if(mat == null){return;}//获得当前材质球使用的ShaderShader shader = mat.shader;//创建一个临时的材质球Material newMat = new Material(shader);//获得Shader声明的变量的数量int propCount = ShaderUtil.GetPropertyCount(shader);for(int i = 0;i<propCount;i++){//获得变量的类型ShaderUtil.ShaderPropertyType propType = ShaderUtil.GetPropertyType(shader,i);//获得变量的名称string propName = ShaderUtil.GetPropertyName(shader, i);//根据变量类型赋值switch(propType){case ShaderUtil.ShaderPropertyType.Float:newMat.SetFloat(propName, mat.GetFloat(propName));break;case ShaderUtil.ShaderPropertyType.Range:newMat.SetFloat(propName, mat.GetFloat(propName));break;case ShaderUtil.ShaderPropertyType.Vector:newMat.SetVector(propName, mat.GetVector(propName));break;case ShaderUtil.ShaderPropertyType.Color:newMat.SetColor(propName, mat.GetColor(propName));break;case ShaderUtil.ShaderPropertyType.TexEnv:newMat.SetTexture(propName, mat.GetTexture(propName));break;                }}//复制材质球参数mat.CopyPropertiesFromMaterial(newMat);//保存材质球EditorUtility.SetDirty(mat);AssetDatabase.SaveAssets();AssetDatabase.Refresh();
}

相关文章:

Unity引擎材质球残留贴图引用的处理

大家好&#xff0c;我是阿赵。   这次来分享一下Unity引擎材质球残留贴图引用的处理 一、 问题 在使用Unity调整美术效果的时候&#xff0c;我们很经常会有这样的操作&#xff0c;比如&#xff1a; 1、 同一个材质球切换不同的Shader、 比如我现在有2个Shader&#xff0c;…...

Flutter鸿蒙next中封装一个列表组件

1. 创建Flutter项目 首先&#xff0c;确保你已经安装了Flutter SDK&#xff0c;并创建一个新的Flutter项目&#xff1a; flutter create podcast_app cd podcast_app2. 封装列表组件 我们将在lib目录下创建一个新的文件&#xff0c;命名为podcast_list.dart&#xff0c;用于…...

层次与网络的视觉对话:树图与力引导布局的双剑合璧

目录 目的内容树图绘制目的步骤参考代码结果与分析 力引导布局算法目的参考代码结果与分析 总结 目的 掌握常用可视化软件与工具&#xff1a;学习和熟练使用常用的数据可视化软件和工具&#xff0c;如Matplotlib、Seaborn、Plotly、Tableau等。这些工具提供了用于创建图表、图…...

python将数据集中所有文件名升序制作txt文件(医学影像)

import os import re # 设定图像文件所在的路径 img_path ./2d/images/ #需修改路径 # 获取该路径下的所有文件名 img_list os.listdir(img_path) # 过滤出以.nii结尾的文件名 nii_list [f for f in img_list if f.endswith(.nii)] # 使用正则表达式从文件名中提…...

【The Art of Unit Testing 3_自学笔记06】3.4 + 3.5 单元测试核心技能之:函数式注入与模块化注入的解决方案简介

文章目录 3.4 函数式依赖注入技术 Functional injection techniques3.5 模块化依赖注入技术 Modular injection techniques 写在前面 上一篇的最后部分对第三章后续内容做了一个概括性的梳理&#xff0c;并给出了断开依赖项的最简单的实现方案&#xff0c;函数参数值注入法。本…...

【VSCode】配置

安装插件 C vscode-icons gdb调试 https://www.bilibili.com/video/BV15U4y1x7b2/?spm_id_from333.999.0.0&vd_sourcedf0ce73d9b9b61e6d4771898f1441f7f https://www.bilibili.com/video/BV1pU4y1W74Z?spm_id_from333.788.recommend_more_video.-1&vd_sourcedf0…...

Linux 常用命令整理大全及命令使用心得

本文章是为了总结自己用过的命令&#xff0c;以及一些心得&#xff0c;网上有很多类似的&#xff0c;但自己总结才能更好的理解。 文章目录 一、文件和目录管理01、 ls &#xff1a;列出目录内容02、cd&#xff1a;更改当前目录03、pwd&#xff1a;显示当前工作目录04、mkdir&a…...

计算器的实现

计算器的⼀般实现 计算器的一般实现&#xff1a;优化&#xff1a;使⽤函数指针数组的实现&#xff1a; 计算器的一般实现&#xff1a; #include <stdio.h> int add(int a, int b) {return a b; } int sub(int a, int b) {return a - b; } int mul(int a, int b) {retur…...

这个工具帮你快速实现数据集成和同步

在这个信息爆炸的时代&#xff0c;数据的流动和同步逐渐成为企业运营的命脉。然而&#xff0c;企业正面临着前所未有的数据挑战&#xff0c;无论是跨地域的分公司协作&#xff0c;还是云服务与本地数据库的交互&#xff0c;数据的集成、清洗、转换和加载&#xff08;ETL&#x…...

论文阅读:Computational Long Exposure Mobile Photography (一)

这篇文章是谷歌发表在 2023 ACM transaction on Graphic 上的一篇文章&#xff0c;介绍如何在手机摄影中实现长曝光的一些拍摄效果。 Abstract 长曝光摄影能拍出令人惊叹的影像&#xff0c;用运动模糊来呈现场景中的移动元素。它通常有两种模式&#xff0c;分别产生前景模糊或…...

项目解决方案:多地连锁药店高清视频监控系统建设解决方案(设计方案)

​ 目录 一.项目背景 1.1背景描述 1.2需求分析 二.设计依据和建设目标 2.1设计依据 2.2建设目标 三.系统设计实现 3.1系统方案设计 3.2网络组网说明 四.建设系统特色 4.1安全性 4.2节约建设成本 4.3原有资源的再利用 4.4可扩展性 五.产品介绍 5.1概述 5.2设备…...

utf-8、pbkdf2_sha

#utf-8加密、解密 import base64 base64.b64encode(lienlien123.encode(utf-8)) bbGllbmxpZW4xMjM base64.b64decode(bbGllbmxpZW4xMjM.decode(utf-8)) blienlien123 #pbkdf2_sha加密&#xff0c;校验 # 该种密码在不同时刻会有产生不同的加密结果 # 该加密方法使用的是散列…...

Java之包,抽象类,接口

目录 包 导入包 静态导入 将类放入包 常见的系统包 抽象类 语法规则 注意事项&#xff1a; 抽象类的作用 接口 实现多个接口 接口间的继承 接口使用实例 &#xff08;法一&#xff09;实现Comparable接口的compareTo()方法 &#xff08;法二&#xff09;实现Comp…...

HarmonyOS鸿蒙开发入门,常用ArkUI组件学习(二)

书接上回&#xff0c;让我们继续来学习ArkUI的其他组件 目录&#xff0c;可以点击跳转到想要了解的组件详细内容 组件四&#xff1a;Button组件五&#xff1a;Slider组件六&#xff1a; Column & Row组件七&#xff1a;循环控制组件八&#xff1a; List 组件四&#xff1a;…...

斩!JavaScript语法进阶

一、DOM 概述 DOM 是 JavaScript 操作网页的接口&#xff0c;全称为“文档对象模型”&#xff08;Document Object Model&#xff09;。当网页被加载时&#xff0c;浏览器将网页转为一个DOM&#xff0c;并用JS进行各种操作。比如&#xff1a;改变页面中的HTML 元素及其属性&am…...

UFO:Windows操作系统的具象智能代理

近年来&#xff0c;随着AI技术的发展&#xff0c;智能代理在各种应用中扮演着越来越重要的角色。微软推出的UFO&#xff08;User-Focused Operator&#xff09;正是这样一个出色的多代理框架&#xff0c;旨在通过无缝导航和操作&#xff0c;满足用户在Windows操作系统中跨多个应…...

win10/11无休眠设置和断电后电池模式自动休眠而不是睡眠-用以省电

1、打开休眠设置选项 打开控制面板\所有控制面板项\电源选项\ 左侧的选择电源按钮的功能 默认状态没有休眠 1、管理员权限打开cmd或者power shell 2、输入一下指令&#xff0c;打开休眠选项 powercfg -hibernate on关闭后重新打开 控制面板\所有控制面板项\电源选项\左侧的选…...

【动态规划之斐波那契数列模型】——累加递推型动态规划

文章目录 第N个泰波那契数列面试题08.01.三步问题使用最小花费爬楼梯解码问题 第N个泰波那契数列 解题思路&#xff1a; 泰波那契数列的第 N 项定义为前面三项之和&#xff0c;即 T0 0, T1 1, T2 1&#xff0c;从 T3 开始&#xff0c;每一项都等于前三项的和。要找到第 N 项…...

5g通信系统用到的crc码

5g通信系统用到的crc码 关注 在5G通信系统中&#xff0c;CRC码&#xff08;循环冗余校验码&#xff09;扮演着关键角色&#xff0c;它通过执行多项式除法运算来检测数据在传输过程中是否发生错误。5G通信系统中采用了多种CRC码&#xff0c;每种码都有其独特的计算方法和校验特…...

Ubuntu-22.04 虚拟机安装

1. Ubuntu安装方式 1.1. 基于物理介质安装 光盘安装&#xff1a;通过将 Ubuntu 镜像刻录到光盘&#xff0c;在计算机 BIOS/UEFI 中设置光盘为第一启动项&#xff0c;然后按照安装程序的提示进行语言选择、分区、用户信息设置等操作来完成安装。这种方式需要有光盘刻录设备和空…...

Windows、Linux系统上进行CPU和内存压力测试

CPU和内存压力测试 1. Linux环境 Linux环境下&#xff0c;我们可以用 stress 工具进行内存、CPU等的压力测试。 【1】. stress工具说明 [kalamikysrv1 ~]$ stress --help stress imposes certain types of compute stress on your systemUsage: stress [OPTION [ARG]] ...-…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发八,使用SDLVSQT显示yuv文件 ,使用ffmpeg的AVFrame

一. AVFrame 核心回顾&#xff0c;uint8_t *data[AV_NUM_DATA_POINTERS] 和 int linesize[AV_NUM_DATA_POINTERS] AVFrame 存储的是解码后的数据&#xff0c;&#xff08;包括音频和视频&#xff09;例如&#xff1a;yuv数据&#xff0c;或者pcm数据&#xff0c;参考AVFrame结…...

HTML 标签属性——<a>、<img>、<form>、<input>、<table> 标签属性详解

文章目录 1. `<a>`元素属性hreftargetname2. `<img>`元素属性srcaltwidth 和 height3. `<form>`元素属性actionmethodenctype4. `<input>`元素属性typevaluenamereadonly5. `<table>`元素属性cellpaddingcellspacing小结HTML元素除了可以使用全局…...

css简写属性

一些属性&#xff0c;如 font、background、padding、border 和 margin 等属性称为简写属性。它们允许在一行中设置多个属性值&#xff0c;从而节省时间并使代码更整洁。 /* 在像 padding 和 margin 这样的 4 值简写语法中&#xff0c;数值的应用顺序是上、右、下、左&#xff…...

力扣刷题(sql)--零散知识点(2)

1.自定义分组后的分类统计问题&#xff08;某组内无数据却仍要展示&#xff09; 例题1&#xff1a; 查询每个工资类别的银行账户数量。 工资类别如下&#xff1a; "Low Salary"&#xff1a;所有工资 严格低于 20000 美元。"Average Salary"&#xff1a;…...

TCP是怎样工作的网络拥塞控制理论和算法部分记录

参考资料 https://github.com/ituring/tcp-book 流量控制、窗口控制和拥塞控制的关系 流量控制、窗口控制和拥塞控制的关系如图所示 窗口控制是上层的概念&#xff0c;核心思路是基于滑动窗口技术传输数据。而确定发送窗口大小的方法有流量控制和拥塞控制两种 流量控制&…...

CSRF初级靶场

靶场 针对DVWA么有防御 源码&#xff1a; <?phpif( isset( $_GET[ Change ] ) ) {// Get input$pass_new $_GET[ password_new ];$pass_conf $_GET[ password_conf ];// Do the passwords match?if( $pass_new $pass_conf ) {// They do!$pass_new ((isset($GLOBA…...

CSP/信奥赛C++刷题训练:经典差分例题(2):洛谷P9904 :Mieszanie kolorów

CSP/信奥赛C++刷题训练:经典差分例题(2):洛谷P9094 :Mieszanie kolorw 题目描述 题目译自 PA 2020 Runda 1 Mieszanie kolorw Byteasar 正准备给栅栏涂漆。他已经准备了 n n n 罐白色油漆,他把这些油漆排列成一排,从 1 1 1 到 n n n 编号。他想用这些油漆,但他不想…...

Java | Leetcode Java题解之第525题连续数组

题目&#xff1a; 题解&#xff1a; class Solution {public int findMaxLength(int[] nums) {int maxLength 0;Map<Integer, Integer> map new HashMap<Integer, Integer>();int counter 0;map.put(counter, -1);int n nums.length;for (int i 0; i < n;…...

YOLOv8改进 - 注意力篇 - 引入iRMB注意力机制

#YOLO# #目标检测# #计算机视觉# 一、本文介绍 作为入门性篇章&#xff0c;这里介绍了iRMB注意力在YOLOv8中的使用。包含iRMB原理分析&#xff0c;iRMB的代码、iRMB的使用方法、以及添加以后的yaml文件及运行记录。 二、iRMB原理分析 iRMB官方论文地址&#xff1a;文章 iR…...