123456833 发表于 2023-4-4 06:44

Unity UI Shader 基础模板

一、前言

这篇文章内容包括:

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

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

Properties
{
        _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
        _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
:此属性的纹理值将以MaterialPropertyBlock的形式从渲染器数据中获取,即unity会自动将 UI的Image Component的Source Image传入。(似乎可以用于批处理,提高性能)。
_Stencil:模板测试相关属性,Unity会自动修改参数,UI可以使用模板测试进行不显示,比如Mask。
_ColorMask:设置颜色通道写入遮罩。写入 ColorMask 0 可关闭对所有颜色通道的渲染。默认模式是 写入所有通道 (RGBA),但是对于某些特殊效果,希望不修改某些通道,或完全禁用颜色写入。
_UseUIAlphaClip是 是否用clip来进行不显示 。, 如果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
                Comp
                Pass
                ReadMask
                WriteMask
        }

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

Shader "UI/CommonUI"
{
    Properties
    {
                _MainTex ("Texture", 2D) = "white" {}
                // 模板测试属性 和 ColorMask 一般不控制,所以在属性面板上隐藏
                _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
    }
    SubShader
    {
                Tags
                {
                        "Queue"="Transparent"
                        "IgnoreProjector"="True"
                        "RenderType"="Transparent"
                        "PreviewType"="Plane"
                        "CanUseSpriteAtlas"="True"
                }
                Stencil
                {
                        Ref
                        Comp
                        Pass
                        ReadMask
                        WriteMask
                }
                Cull Off
                Lighting Off
                ZWrite Off
                ZTest
                Blend SrcAlpha OneMinusSrcAlpha
                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
      }
    }
}

LiteralliJeff 发表于 2023-4-4 06:48

[赞同]

stonstad 发表于 2023-4-4 06:52

[赞同]

HuldaGnodim 发表于 2023-4-4 06:53

模板的ColorMask 的_ColorMask哪里来的,官方默认shader是定义了_ColorMask变量,这个模板没有,是不是漏了?

JamesB 发表于 2023-4-4 07:00

[赞同]

jquave 发表于 2023-4-4 07:06

有URP下的吗[爱]
页: [1]
查看完整版本: Unity UI Shader 基础模板