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

Unity URP渲染管线动态修改材质球状态

最近工作过程中,有遇到需要动态修改模型材质球的情况,然后发现这点内置管线和URP还是有一些区别的,所以整理总结一下。

自定义结构体

我这里用到方法是创建一个自定义的结构体,结构体内写入对应的字段来存储材质球的各种属性,这里是我创建的一个结构体:

[System.Serializable]
//初始材质状态
public struct MaterialState
{// URP渲染模式public int surfaceType;              // 表面类型(0-不透明 1-透明)public int blendMode;                // 混合模式(1=Alpha混合,2=Premultiply等)public int renderFace;               //渲染面 (0-双面 1-背面 2-正面)// 基础属性public Color albedoColor;            // 基础颜色public Texture albedoMap;            // 纹理贴图public string renderTypeTag;         // 渲染类型标签public int renderQueue;              // 渲染队列public CompareFunction zTest;        // 深度测试模式public int zWrite;                   // 深度写入public MaterialGlobalIlluminationFlags globalIlluminationFlags;// URP PBR属性public float metallic;               // 金属度 [0-1]public float smoothness;             // 光滑度 [0-1]public Texture metallicSmoothnessMap;// 金属光滑度贴图//增强属性public Texture normalMap;            //法线贴图public float normalStrength;         //法线强度// 自发光属性(URP增强版)public bool isEmission;              // 是否启用自发光public Color emissionColor;          // 自发光颜色public float emissionIntensity;      // 自发光强度public Texture emissionMap;          // 自发光贴图public bool emissionUseGlobalIllumination; // 自发光是否影响全局光照// URP关键字状态public List<string> enabledKeywords; // 已启用的Shader关键字
}

保存材质球状态

Unity里动态保存或者修改材质球属性,都是通过调用Material类的API,通过关键字查找到材质球对应的属性,进行保存或修改。

初始化保存材质球方法:

    public static MaterialState SaveMaterialState(Material mat){// 初始化材质状态结构体MaterialState state = new MaterialState();if (mat == null){Debug.LogError("尝试保存空材质的状态");return state;}if (mat.HasProperty("_Surface")){state.surfaceType = mat.GetInt("_Surface");}if (mat.HasProperty("_Blend")){state.blendMode = mat.GetInt("_Blend");}if (mat.HasProperty("_Cull")){Debug.Log("当前渲染面:" + mat.GetInt("_Cull"));state.renderFace = mat.GetInt("_Cull");}// 基础属性state.renderTypeTag = mat.GetTag("RenderType", false, "");state.renderQueue = mat.renderQueue;// 基础颜色和纹理(URP标准属性)state.albedoColor = mat.HasProperty("_BaseColor") ? mat.GetColor("_BaseColor") :(mat.HasProperty("_Color") ? mat.GetColor("_Color") : Color.white);state.albedoMap = mat.HasProperty("_BaseMap") ? mat.GetTexture("_BaseMap") :(mat.HasProperty("_MainTex") ? mat.GetTexture("_MainTex") : null);// 深度测试if (mat.HasProperty("_ZTest")){state.zTest = (CompareFunction)mat.GetInt("_ZTest");}if (mat.HasProperty("_ZWrite")){state.zWrite = mat.GetInt("_ZWrite");}// URP PBR属性state.metallic = mat.HasProperty("_Metallic") ? mat.GetFloat("_Metallic") : 0f;//金属度state.smoothness = mat.HasProperty("_Smoothness") ? mat.GetFloat("_Smoothness") :(mat.HasProperty("_Glossiness") ? mat.GetFloat("_Glossiness") : 0.5f);//光滑度state.metallicSmoothnessMap = mat.HasProperty("_MetallicGlossMap") ?mat.GetTexture("_MetallicGlossMap") : null;//增强属性state.normalMap = mat.HasProperty("_BumpMap") ? mat.GetTexture("_BumpMap") : null;state.normalStrength = mat.HasProperty("_BumpScale") ? mat.GetFloat("_BumpScale"):0;//自发光属性state.isEmission = mat.IsKeywordEnabled("_EMISSION");if (mat.HasProperty("_EmissionColor")){state.emissionColor = mat.GetColor("_EmissionColor");}if (mat.HasProperty("_EmissionIntensity")){state.emissionIntensity = mat.GetFloat("_EmissionIntensity");}else{//  fallback: 使用颜色分量最大值state.emissionIntensity = state.emissionColor.maxColorComponent;}state.emissionMap = mat.HasProperty("_EmissionMap") ? mat.GetTexture("_EmissionMap") : null;state.emissionUseGlobalIllumination = (mat.globalIlluminationFlags &MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;// 保存材质关键字状态(URP关键特性)state.enabledKeywords = new List<string>(mat.shaderKeywords);// 全局光照设置state.globalIlluminationFlags = mat.globalIlluminationFlags;return state;}

恢复材质球初始状态(动态修改材质球)

  public static void RestoreMaterialState(Material mat, MaterialState state){if (mat == null){Debug.LogError("无法恢复空材质的状态");return;}// 1. 恢复URP核心渲染模式(替代传统_Mode)if (mat.HasProperty("_Surface")){mat.SetInt("_Surface", state.surfaceType); // 表面类型(0=不透明,1=透明等)}if (mat.HasProperty("_Blend")){mat.SetInt("_Blend", state.blendMode); // 混合模式}if (mat.HasProperty("_Cull")){mat.SetInt("_Cull", state.renderFace);}// 2. 恢复渲染类型标签和队列mat.SetOverrideTag("RenderType", state.renderTypeTag);mat.renderQueue = state.renderQueue;// 3. 恢复深度测试和写入设置(URP关键属性)if (mat.HasProperty("_ZTest")){mat.SetInt("_ZTest", (int)state.zTest); // 深度测试模式}if (mat.HasProperty("_ZWrite")){mat.SetInt("_ZWrite", state.zWrite); // 深度写入}// 4. 恢复基础颜色和纹理  URP一般是_BaseColorif (mat.HasProperty("_BaseColor")){mat.SetColor("_BaseColor", state.albedoColor); // 基础颜色}else if (mat.HasProperty("_Color")){mat.SetColor("_Color", state.albedoColor); // 兼容传统属性}if (mat.HasProperty("_BaseMap") && state.albedoMap != null){mat.SetTexture("_BaseMap", state.albedoMap); // URP基础纹理}else if (mat.HasProperty("_MainTex") && state.albedoMap != null){mat.SetTexture("_MainTex", state.albedoMap); // 兼容传统纹理}// 5. 恢复PBR属性(金属度/光滑度)if (mat.HasProperty("_Metallic")){mat.SetFloat("_Metallic", state.metallic);}if (mat.HasProperty("_Smoothness")){mat.SetFloat("_Smoothness", state.smoothness);}else if (mat.HasProperty("_Glossiness")){mat.SetFloat("_Glossiness", state.smoothness); // 兼容光泽度}if (mat.HasProperty("_MetallicGlossMap") && state.metallicSmoothnessMap != null){mat.SetTexture("_MetallicGlossMap", state.metallicSmoothnessMap); // URP金属光滑度贴图}// 6.恢复增强属性if (mat.HasProperty("_BumpMap") && state.normalMap != null){mat.SetTexture("_BumpMap", state.normalMap);}if (mat.HasProperty("_BumpScale")){mat.SetFloat("_BumpScale", state.normalStrength);}// 7. 恢复自发光属性if (mat.HasProperty("_EmissionColor")){mat.SetColor("_EmissionColor", state.emissionColor);}if (mat.HasProperty("_EmissionIntensity")){mat.SetFloat("_EmissionIntensity", state.emissionIntensity); // URP单独强度控制}if (mat.HasProperty("_EmissionMap") && state.emissionMap != null){mat.SetTexture("_EmissionMap", state.emissionMap);}// 恢复自发光关键字和全局光照影响SetKeyword(mat, "_EMISSION", state.isEmission);if (state.isEmission){// 控制自发光是否影响全局光照mat.globalIlluminationFlags = state.emissionUseGlobalIllumination? state.globalIlluminationFlags & ~MaterialGlobalIlluminationFlags.EmissiveIsBlack: state.globalIlluminationFlags | MaterialGlobalIlluminationFlags.EmissiveIsBlack;}// 8. 恢复全局光照设置mat.globalIlluminationFlags = state.globalIlluminationFlags;}private static void SetKeyword(Material material, string keyword, bool state){if (state){material.EnableKeyword(keyword);}else{material.DisableKeyword(keyword);}}

我这里基本上只是选择了材质球里比较常用的属性举例,如果有别的需要修改的属性,可以修改一下结构体,找到那个属性对应的关键字,再根据需求添加就可以。

http://www.lryc.cn/news/612611.html

相关文章:

  • 38.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--增加日志记录器
  • 十八、k8s细粒度流量管理:服务网格
  • 虚幻GAS底层原理解剖八 (自定义子类)
  • 深入剖析Java线程:从基础到实战(上)
  • Clock斗篷技术:助力跨境电商营销推广的智慧策略
  • 技术优势铸就行业标杆:物联网边缘计算网关凭何引领智能变革?
  • 以 Eland 玩转 Elasticsearch 8.12 Learning-to-Rank
  • 嵌入式C语言编程:策略模式、状态模式和状态机的应用
  • 蓝凌EKP产品:列表查询性能优化全角度
  • Git 文件删除操作指南:管理与恢复已删除文件
  • 合约收款方式,转账与问题安全
  • 「耘•学社」耘少年第五期学能突破导师制领袖特训营,圆满落幕
  • 计算机视觉前言-----OpenCV库介绍与计算机视觉入门准备
  • 解决Git提交人信息默认全局化问题:让提交人自动关联当前用户
  • Element Plus实现分页查询
  • 【PHP 中的 `use` 关键字完全指南】
  • 数码论坛|基于SprinBoot+vue的数码论坛系统(源码+数据库+文档)
  • Redis为什么要引入多线程?
  • Beelzebub靶机
  • 防火墙环境下的全网服务器数据自动化备份平台搭建:基于 rsync 的完整实施指南
  • Java基础学习1(Java语言概述)
  • spring cache(二)核心接口
  • 浏览器渲染与GPU进程通信图解
  • ubuntu 2024 安装拼音输入法
  • 纪念《信号与系统》拉普拉斯变换、Z变换之前内容学完
  • 迭代器与生成器:Python 中的高效数据遍历机制
  • 现代制冷系统核心技术解析:从四大件到智能控制的关键突破
  • QDataStream入门
  • LeetCode每日一题,2025-8-7
  • JSON、JSONObject、JSONArray详细介绍及其应用方式