当前位置: 首页 > 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.dtcms.com/a/318802.html

相关文章:

  • 基于 HT 引擎实现 3D 智慧物流转运中心一体化管控系统
  • 【CS创世SD NAND征文】小型夜灯为何需要存储芯片?从基础照明到智能存储的升级密码
  • 生成式AI时代,Data+AI下一代数智平台建设指南
  • EP04:【DL 第二弹】张量的线性代数运算
  • 内网穿透原理和部署教程
  • 京东关键字搜索商品列表接口开发实战:从参数优化到分布式调用
  • localforage的数据仓库、实例、storeName和name的概念和区别
  • VBA之Word应用第四章第一节:段落集合Paragraphs对象(一)
  • mysql全屏终端全量、部分备份、恢复脚本
  • 累加和校验原理与FPGA实现
  • 躺平发育小游戏微信抖音流量主小程序开源
  • 自建纯竞拍系统小程序需准备的事项
  • uniapp/uniappx实现图片或视频文件选择时同步告知权限申请目的解决华为等应用市场上架审核问题
  • TSMaster-C小程序使用
  • uni-app X能成为下一个Flutter吗?
  • Dify 从入门到精通(第 20/100 篇):Dify 的自动化测试与 CI/CD
  • MyBatis-Plus Service 接口:如何在 MyBatis-Plus 中实现业务逻辑层??
  • 阿里云部署若依后,浏览器能正常访问,但是apifox和小程序访问后报错链接被重置
  • [失败记录] 使用HBuilderX创建的uniapp vue3项目添加tailwindcss3的完整过程
  • [无需 Mac] 使用 GitHub Actions 构建 iOS 应用
  • vue3 el-select 加载内容后 触发事件
  • 「耘•学社」耘少年第五期学能突破导师制领袖特训营,圆满落幕
  • C++与SparkAI实战:高效应用案例
  • Android-Kotlin基础(Jetpack②-Data Binding)
  • 国产化Excel处理组件Spire.XLS教程:使用 C# 将 DataTable 导出为 Excel 文件
  • 嵌入式C语言编程:策略模式、状态模式和状态机的应用
  • 东莞立晟精密硅胶科技有限公司将携重磅产品亮相 AUTO TECH China 2025 广州国际汽车技术展
  • 计算机网络1-4:计算机网络的定义和分类
  • 汽车娱乐信息系统域控制器的网络安全开发方案
  • FPGA实战:用PL端串口发送Hello world