• 设置Unity URP管线中的渲染开关


    在上一节中,我们添加了外轮廓线,但这个外轮廓线在所有使用该Shader的网格上是始终存在的。

    如果我们想做一个开关,决定是否打开外轮廓线时,我们可以使用一个新的Uniform bool值,然后判断bool是否为true来开启外轮廓线。

    但是这样会造成性能的浪费,因为就算我们没有开启这个功能,Shader还是会遍历每一个if条件。这与GPU的运行原理有关。
    故我们使用Unity的多编译功能,将Shader多次编译成多个子Shader。

    Shader中添加开关

    定义开关名称

    // 自定义关键字
    [Toggle(_ENABLE_OUTLINE_ON)] _EnableOutline("Enable OutLine", Float) = 0.0
    // 默认关键字(默认为 名称大写+_ON)
    [Toggle] _EnableOutline("Enable OutLine", Float) = 0.0
    // 默认关键字为(_ENABLEOUTLINE_ON)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在Input中声明变量

    1.
    half _EnableInline;
    
    2.
    #ifdef UNITY_DOTS_INSTANCING_ENABLED
    UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    	...
    	UNITY_DOTS_INSTANCED_PROP(float , _EnableInline)
    UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    
    3.
    #define _EnableInline           UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float  , Metadata__EnableInline)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    定义关键字

    //pass中定义
    #progma shader_feature _ENABLE_OUTLINE_ON//自定义关键字
    #progma shader_feature _ENABLEOUTLINE_ON//默认关键字
    
    • 1
    • 2
    • 3

    使用关键字

    #if defined(_ENABLE_OUTLINE_ON)
    
    #else
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在GUI中设置开关,来控制该关键字

    在子GUI面板中添加按钮设置Shader中变量值

    public static class Styles
    {
        public static readonly GUIContent InlineEnable = new GUIContent("开启内勾边",
            "");
    }
    
    public struct LitProperties
    {
        public MaterialProperty InlineEnabled;
        
        public LitProperties(MaterialProperty[] properties)
        {
            InlineEnabled = BaseShaderGUI.FindProperty("_EnableInline", properties, false);
        }
    }
    
    /// 
    /// 当滚轮滑动材质Inspector面板时,该函数调用4+次
    /// 当修改参数或点击按钮时,该函数也会调用约8-12次
    /// 因此可将该函数看作多次遍历的函数
    /// 
    public static void DoDetailArea(LitProperties properties, MaterialEditor materialEditor)
    {
        materialEditor.ColorProperty(properties.OutLineColor, Styles.OutLineColorContent.text);
        materialEditor.FloatProperty(properties.OutLineSize, Styles.OutLineSizeContent.text);
    
        // 显示按钮,设置GUI按钮的值,返回开关选中的状态
        bool inlineEnabled = EditorGUILayout.Toggle(Styles.InlineEnable, properties.InlineEnabled.floatValue > 0.5f);
        // 根据按钮的选中状态修改Shader值
        properties.InlineEnabled.floatValue = inlineEnabled ? 1f : 0f;
    
        // BeginDisabledGroup参数填True,则为禁用Begin至End直接的功能。在untiy面板上置灰。
        EditorGUI.BeginDisabledGroup(!inlineEnabled);
        {
            materialEditor.FloatProperty(properties.InlineSize, Styles.InlineSizeContent.text);
            materialEditor.FloatProperty(properties.Inlineluminance, Styles.InlineluminanceContent.text);
            materialEditor.FloatProperty(properties.HightLightTransition, Styles.HightLightTransitionContent.text);
        }
        EditorGUI.EndDisabledGroup();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    此时,便可以通过按钮设置properties.InlineEnabled.floatValue的值了。

    根据Shader中变量值,设置宏的值

    根据Shader中变量值"_EnableInline",设置宏"_ENABLE_INLINE_ON"的值

    public static void SetMaterialKeywords(Material material)
    {
        if (material.HasProperty("_EnableInline"))
        {
            bool isSnowEnabled = material.GetFloat("_EnableInline") > 0.5f;
            CoreUtils.SetKeyword(material, "_ENABLE_INLINE_ON", isSnowEnabled);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当用户使用这个ShaderGUI将材质加载到内存中或者改变Inspector中的值时,编辑器调用下面这个方法。我们在这个方法中调用SetMaterialKeywords函数

    public override void ValidateMaterial(Material material)
    {
        CP_DragonOutLineGUI.SetMaterialKeywords(material);
    }
    
    • 1
    • 2
    • 3
    • 4

    该方法可用于设置材质中的各个宏定义。

  • 相关阅读:
    8+NAM+分型+单细胞生信思路
    java企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)
    使用serverless超低成本快速部署开源项目
    OpenCV(十九):模板匹配
    简单介绍神经网络中不同优化器的数学原理及使用特性【含规律总结】
    http协议
    自动化运维工具Ansible工具学习及使用---持续更新中
    2022年湖北师范大学招生简章--成人高等教育高起专、专升本学历提升
    小程序源码:全新独立后台月老办事处一元交友盲盒-多玩法安装简单
    计算机五大部件是指什么
  • 原文地址:https://blog.csdn.net/weixin_44518102/article/details/133943635