找回密码
 立即注册
查看: 278|回复: 5

Unity UI Shader 基础模板

[复制链接]
发表于 2023-4-4 06:44 | 显示全部楼层 |阅读模式
一、前言

这篇文章内容包括:

  • 对于Unity 官方Default UI模板 的注释
  • 自定义 UI shader 模板
这是我整理通用Unity UI shader 系列的文章之一,因为最近比较忙没有时间搭博客,内容会先更新在知乎上。
参考:
二、Unity Default UI 模板

UIShader因为要让图片渲染跟rectTransform组件相匹配,所以一般的shader无法直接用在UI上
2.1 Properties

Properties
{
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255
        _ColorMask ("Color Mask", Float) = 15
        [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
[PerRendererData] 此属性的纹理值将以MaterialPropertyBlock的形式从渲染器数据中获取,即unity会自动将 UI的Image Component的Source Image传入。(似乎可以用于批处理,提高性能)。
_Stencil:模板测试相关属性,Unity会自动修改参数,UI可以使用模板测试进行不显示,比如Mask。
_ColorMask:设置颜色通道写入遮罩。写入 ColorMask 0 可关闭对所有颜色通道的渲染。默认模式是 写入所有通道 (RGBA),但是对于某些特殊效果,希望不修改某些通道,或完全禁用颜色写入。
_UseUIAlphaClip是 是否用clip来进行不显示 。[Toggle(UNITY_UI_ALPHACLIP)], 如果Toggle是true , 则自动#define UNITY_UI_ALPHACLIP ,可以用#ifdef进行预处理。
2.2 SubShader

UIShader是AB(alpha blend)类型的shader,跟透明混合一样,在subshader中需要设置特殊变量,并且关闭深度写入
SubShader
{
        Tags
        {
                "Queue"="Transparent" // UI存在透明图片,所以渲染队列是 Transparent
                "IgnoreProjector"="True" // 忽略投影器Projector
                "RenderType"="Transparent" // 渲染模式
                "PreviewType"="Plane" // UI预览的正常都是一个平面(Plane)
                "CanUseSpriteAtlas"="True" // UI经常使用图集,所以要设置图集可以使用
        }

        Stencil
        {      
                // UI 模板测试,把在Properties中定义的模板参数导入,Unity会自动修改
                Ref [_Stencil]
                Comp [_StencilComp]
                Pass [_StencilOp]
                ReadMask [_StencilReadMask]
                WriteMask [_StencilWriteMask]
        }

        Cull Off // 剔除关闭
        Lighting Off // 光照关闭
        ZWrite Off // 深度写入关闭
        ZTest [unity_GUIZTestMode] // 用于UI组件的shader都要包含一句:ZTest [unity_GUIZTestMode],以确保UI能在前层显示
        Blend SrcAlpha OneMinusSrcAlpha // 混合模式是 OneMinusSrcAlpha 正常模式(透明度混合)
        ColorMask [_ColorMask] // 将定义的_ColorMask参数导入
.....
}
三、自定义 UI Shader 模板

Shader "UI/CommonUI"
{
    Properties
    {
                [PerRendererData] _MainTex ("Texture", 2D) = "white" {}
                // 模板测试属性 和 ColorMask 一般不控制,所以在属性面板上隐藏
                [HideInInspector]_StencilComp ("Stencil Comparison", Float) = 8
                [HideInInspector]_Stencil ("Stencil ID", Float) = 0
                [HideInInspector]_StencilOp ("Stencil Operation", Float) = 0
                [HideInInspector]_StencilWriteMask ("Stencil Write Mask", Float) = 255
                [HideInInspector]_StencilReadMask ("Stencil Read Mask", Float) = 255
    }
    SubShader
    {
                Tags
                {
                        "Queue"="Transparent"
                        "IgnoreProjector"="True"
                        "RenderType"="Transparent"
                        "PreviewType"="Plane"
                        "CanUseSpriteAtlas"="True"
                }
                Stencil
                {
                        Ref [_Stencil]
                        Comp [_StencilComp]
                        Pass [_StencilOp]
                        ReadMask [_StencilReadMask]
                        WriteMask [_StencilWriteMask]
                }
                Cull Off
                Lighting Off
                ZWrite Off
                ZTest [unity_GUIZTestMode]
                Blend SrcAlpha OneMinusSrcAlpha
                ColorMask [_ColorMask]

        Pass
        {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma multi_compile _ UNITY_UI_ALPHACLIP
                #include "UnityUI.cginc"
                #include "UnityCG.cginc"

                fixed4 _TextureSampleAdd; // Unity管理:图片格式用Alpha8
                float4 _ClipRect;// Unity管理:2D剪裁使用
                sampler2D _MainTex;
                struct a2v{
                        float4 vertex       : POSITION;
                        float4 color        : COLOR;
                        float2 texcoord     : TEXCOORD0;
                        UNITY_VERTEX_INPUT_INSTANCE_ID
                    };
                struct v2f{
                        float4 vertex       : SV_POSITION;
                        float4 color        : COLOR;
                               float2 texcoord     : TEXCOORD0;
                        UNITY_VERTEX_OUTPUT_STEREO
                    };
                    v2f vert(a2v IN){
                        v2f OUT;
                        UNITY_SETUP_INSTANCE_ID(IN);
                        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);// 实例化处理
                        OUT.vertex = UnityObjectToClipPos(IN.vertex);// 模型空间到裁剪空间
                        OUT.color = IN.color;
                        OUT.texcoord = IN.texcoord;
                        return OUT;
                    }
                    fixed4 frag(v2f IN):SV_Target{
                        // 直接读取纹理颜色 并且乘上 ImageColor
                        half4 color = tex2D(_MainTex,IN.texcoord) * IN.color;
                        return color;
                }
                 ENDCG
        }
    }
}
发表于 2023-4-4 06:48 | 显示全部楼层
[赞同]
发表于 2023-4-4 06:52 | 显示全部楼层
[赞同]
发表于 2023-4-4 06:53 | 显示全部楼层
模板的ColorMask [_ColorMask]的_ColorMask哪里来的,官方默认shader是定义了_ColorMask变量,这个模板没有,是不是漏了?
发表于 2023-4-4 07:00 | 显示全部楼层
[赞同]
发表于 2023-4-4 07:06 | 显示全部楼层
有URP下的吗[爱]
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-3 03:03 , Processed in 0.090953 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表