Unity 渲染管线自动转换的实现 支持HDRP转URP,URP转HDRP

news2024/9/20 6:23:39

HDRP和URP无法平滑切换,因为属性、功能差异巨大。
本脚本仅对可对应的默认脚本和属性做了转换处理。细节调整还需自己搞。
自动转换可以节省手动更换shader、texture、通用属性的劳动成本。

操作步骤

  1. 使用前确保当前项目中存在HDRP和URP的包,没有请到packge manager中下载
  2. 将下方代码保存至Editor文件夹中,没有自己创建。
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

class HDRP2URPConverter : MonoBehaviour
{
    // 更新文件夹
    public static string root;
    private static List<TextureResource> m_textureResourceList;
    private static List<ShaderResource> m_shaderPairs;

    [MenuItem("转换管线/HDRP转URP")]
    static void HdrpToUrp()
    {
        ManualValidate();
        WalkthroughMaterials(root, ReplaceToUrp, GetURPShader);
    }
    [MenuItem("转换管线/URP转HDRP")]
    static void UrpToHdrp()
    {
        ManualValidate();
        WalkthroughMaterials(root, ReplaceToHDRP, GetHDRPShader);
    }

    private static string[] m_switchPropertiesList = new string[]
    {
        "_MainTex", "_BaseMap", "_BaseColorMap", "_BaseMap", "_NormalMap", "_BumpMap", "_AlphaCutoffEnabled", "_AlphaClip"
    };

    private static string[] m_shaderNameList = new[]
    {
        "HDRP/Lit", "Universal Render Pipeline/Lit", "HDRP/Unlit", "Universal Render Pipeline/Unlit"
    };

    [ContextMenu("初始化工具")]
    private static void ManualValidate()
    {
        // 更换texture
        m_textureResourceList = new List<TextureResource>();
        for (int i = 0; i < m_switchPropertiesList.Length; i += 2)
        {
            m_textureResourceList.Add(new TextureResource()
            {
                source = m_switchPropertiesList[i],
                target = m_switchPropertiesList[i + 1]
            });
        }

        // 更换shader
        m_shaderPairs = new List<ShaderResource>();
        for (int i = 0; i < m_shaderNameList.Length; i += 2)
        {
            var s = m_shaderNameList[i];
            var t = m_shaderNameList[i + 1];
            m_shaderPairs.Add(new ShaderResource()
            {
                source = Shader.Find(s),
                target = Shader.Find(t)
            });
        }
    }

    public static Shader GetURPShader(Shader source)
    {
        foreach (var s in m_shaderPairs)
        {
            if (s.source == source) return s.target;
        }
        return Shader.Find("Universal Render Pipeline/Lit");
    }
    public static Shader GetHDRPShader(Shader target)
    {
        foreach (var s in m_shaderPairs)
        {
            if (s.target == target) return s.source;
        }
        return Shader.Find("HDRP/Lit");
    }
    public static void ReplaceToUrp(Material mat, Shader s)
    {

        foreach (var p in m_textureResourceList)
        {
            if (mat.HasProperty(p.source))
            {
                p.tex = mat.GetTexture(p.source);
            }
        }

        mat.shader = s;
        foreach (var p in m_textureResourceList)
        {
            if (mat.HasProperty(p.target))
            {
                mat.SetTexture(p.target, p.tex);
            }
        }
    }
    public static void ReplaceToHDRP(Material mat, Shader s)
    {
        foreach (var p in m_textureResourceList)
        {
            if (mat.HasProperty(p.target))
            {
                p.tex = mat.GetTexture(p.target);
            }
        }

        mat.shader = s;
        foreach (var p in m_textureResourceList)
        {
            if (mat.HasProperty(p.source))
            {
                mat.SetTexture(p.source, p.tex);
            }
        }
    }
    public static void WalkthroughMaterials(string folder, Action<Material, Shader> replace, Func<Shader, Shader> getShader)
    {
        folder = "Assets/" + folder;
        string[] allFiles = Directory.GetFiles(folder, "*.mat", SearchOption.AllDirectories);

        foreach (string file in allFiles)
        {
            Material mat = AssetDatabase.LoadAssetAtPath<Material>(file);
            if (mat != null)
            {
                var s = getShader(mat.shader);
                replace(mat, s);
            }
        }
    }
}

[System.Serializable]
public class TextureResource
{
    public string source;
    public string target;
    public Texture tex;
}
[System.Serializable]
public class ShaderResource
{
    public Shader source;
    public Shader target;
    public Texture tex;
}
public 
  1. 点击工具栏-> 转换管线-> HDRP转URP,然后等待处理结束即可
    在这里插入图片描述
  2. 处理好的模型都变粉嫩了。因为你当前是URP/HDRP管线,与转换后的材质不通。切换管线后就能正常看了。
    在这里插入图片描述

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

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

相关文章

Vue.js 学习14 集成H265web.js播放器实现webpack自动化构建

Vue.js 学习14 集成H265web.js播放器实现webpack自动化构建 一、项目说明1. H265web.js 简介2. 准备环境 二、项目配置1. 下载 H265web.js2. 在vue项目里引入 H265web3. 设置 vue.config.js 三、代码引用1. 参照官方demo &#xff0c; 创建 executor.js2. 在 vue 页面里引用htm…

批量检测微信小程序是否封禁接口源码

<?php // 要检测的 appid 列表 $appids array(appid1, appid2, appid3); // 使用实际的 appid // 循环调用接口检测小程序状态 foreach ($appids as $appid) { $url https://yan.changxunwangluo.cn/xcx/check_mini_program.php?appid . urlencode($appid); $…

【已解决】c++ qt选中该行为什么该列部分变色

笔者开启了QTableView中交替行改变颜色&#xff0c;发现笔者自定义绘制的水平滚动条&#xff0c;在选中后不发生颜色改变&#xff0c;这让笔者很疑惑。笔者查阅资料后发现&#xff0c;自定义绘制的控件&#xff0c;要自身设置颜色。当笔者解决了这个问题时&#xff0c;顺手就将…

GPT原始论文:Improving Language Understanding by Generative Pre-Training论文翻译

1 摘要 自然语理解包括文本蕴含、问题回答、语义相似性评估和文档分类等一系列多样化的任务。尽管大量未标注的文本语料库很丰富&#xff0c;但用于学习这些特定任务的标注数据却很稀缺&#xff0c;这使得基于区分性训练的模型难以充分发挥作用。我们展示了通过在多样化的未标…

高级Java开发工程师岗位的基本职责(合集)

高级Java开发工程师岗位的基本职责1 职责&#xff1a; 1、负责区块链产品的研发&#xff0c;独立或与团队合作&#xff0c;按时保质完成软件开发项目; 2、参与产品系统设计、概要设计工作&#xff0c;核心功能的代码编写; 3、独立解决和指导其他同事处理开发中遇到的难点问题; …

GaussDB新体验,新零售选品升级注入新思路【华为云GaussDB:与数据库同行的日子】

选品思维&#xff1a;低频VS高频 一个的商超&#xff0c;假设有50个左右的品类&#xff0c;每个品类下有2到10个不等的商品。然而如此庞大的商品&#xff0c;并非所有都是高频消费品。 结合自身日常的消费习惯&#xff0c;对于高频和低频的区分并不难。一般大型家电、高端礼盒…

14.2 Java正则表达式(❤❤)

14.2 Java正则表达式 1. 正则表达式1.1 简介1.2 字符范围匹配1.3 元字符1.4 多次重复匹配1.5 定位匹配1.6 贪婪模式与非贪婪模式1.7 表达式分组1. 正则表达式 1.1 简介 开源 在线正则表达式测试 1.2 字符范

mapbox 高亮相同特征的要素数据

一、完整代码 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>Highlight features containing similar data</title> <meta name"viewport" content"initial-scale1,maximum-scale1,user-scal…

VUE3+TS使用OpenSeadragon学习之旅,实现多图片切换效果

1.官方网站&#xff1a;OpenSeadragon 2.使用npm下载插件&#xff1a;npm install openseadragon 3.在 index.html文件引入资源 <link rel"stylesheet" href"node_modules/openseadragon/build/openseadragon/openseadragon.css" /><script src…

正点原子--STM32定时器学习笔记(1)

这部分是笔者对基本定时器的理论知识进行学习与总结&#xff01;&#xff0c;主要记录自己在学习过程中遇到的重难点&#xff0c;其他一些基础点就一笔带过了&#xff01; 1. 定时器概述 1.1 软件定时原理 使用纯软件&#xff08;CPU死等&#xff09;的方式实现定时&#xf…

Python之运算符汇总

1.算数运算符 假设 a 10, b 20 2.比较运算符 3.赋值运算符 4.逻辑运算符 逻辑运算的顺序排列:从左往右开始执行 () > not > and > or and or 一真一假 都为真: 取后面的 取前面的 取假的…

sentinel的Context创建流程分析

sentinel入门 功能 限流&#xff1a;通过限制请求速率、并发数或者用户数量来控制系统的流量&#xff0c;防止系统因为流量过大而崩溃或无响应的情况发生。 熔断&#xff1a;在系统出现故障或异常时将故障节点从系统中断开&#xff0c;从而保证系统的可用性。 降级&#xf…

PyTorch 2.2 中文官方教程(十三)

在 C中注册一个分发的运算符 原文&#xff1a;pytorch.org/tutorials/advanced/dispatcher.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 分发器是 PyTorch 的一个内部组件&#xff0c;负责确定在调用诸如torch::add这样的函数时实际运行哪些代码。这可能并不简…

元数据驱动的思想

元数据驱动的思想 元数据驱动的思想应该不会陌生&#xff0c;但元数据驱动的实践应该会非常陌生。 因为元数据驱动架构是为了解决高频个性化的复杂业务而诞生的&#xff0c;而这种业务场景只存在2B领域。 有关元数据驱动的架构思想&#xff0c;在这里暂先简单抛几个点。&#…

【动态规划】【树形dp】【C++算法】968监控二叉树

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode:968监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所…

机器学习:线性判别分析LDA(Python)

一、线性判别分析的定义 二、线性判别分析——二分类模型 lda2classify.py import numpy as npclass LDABinaryClassifier:"""线性判别分析二分类模型"""def __init__(self):self.mu None # 各类别均值向量self.Sw_i None # 各类内散度矩阵…

【电路笔记】-线圈的电感

线圈的电感 文章目录 线圈的电感1、概述2、线圈的电感3、电感示例14、电感示例2 电感是指抵抗流过其的电流变化的元件属性的名称&#xff0c;即使是直的电线也会有一些电感。 1、概述 线圈的电感是指感应线圈抵抗流过其的电流的任何变化所必须的电气特性。 因此&#xff0c;电…

Qt拖拽事件,实现控件内项的相互拖拽

文章目录 1拖拽演示2 步骤3 实现 这里主要以QTableview控件为例&#xff0c;实现表格内数据的相互拖拽。 1拖拽演示 2 步骤 自定以QTableView类&#xff0c;在自定义类中重写拖拽事件&#xff1a; void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent *…

装饰你的APP:使用Lottie-Android创建动画效果

装饰你的APP&#xff1a;使用Lottie-Android创建动画效果 1. Lottie-Android简介 Lottie-Android是一个强大的开源库&#xff0c;由Airbnb开发&#xff0c;旨在帮助开发者轻松地在Android应用中添加高质量的动画效果。它基于Adobe After Effects软件中的Bodymovin插件&#x…

一种缩短轮询时间的处理办法

我们平常处理轮询任务的时候&#xff0c;会用时间片的方式来分割开&#xff0c;每个时间片处理某一个任务。 有时候有些任务并不需要有动作&#xff0c;本轮轮询到它&#xff0c;它不需要干活&#xff0c;于是这个时间片就浪费了。但如果其他时间片里面的任务又急着呢&#xff…