Shader color adjustment by UI components in Unity


Preface

Shader color adjustment by UI components in Unity


1. Principle

The Color property directly exposed in the Shader will not form a property binding with the Color in the Image component of the UI. Because the color changed in the Image component of the UI is the vertex color, if you need to modify the color in the component, the color in the Shader will also change at the same time. Then you need to add a variable to the data passed to the vertex shader at the application stage for use by the vertex shader.


2. Realization

1. In the structure appdata, add a variable with COLOR semantics to represent the incoming vertex color.

//Define a 4-dimensional vector with semantics of Color to pass in the vertex color. After setting the semantics to COLOR, this variable will correspond to the vertex color.
struct appdata
{ //Vertex information float4 vertex:POSITION; float2 uv : TEXCOORD; //Define a 4-dimensional vector with semantics Color here to pass in the vertex color. After setting the semantics to COLOR, this variable will correspond to the vertex color fixed4 color :COLOR; };





2. In the structure v2f, add a variable defined with TEXCOORD1 semantics. The semantics here actually have no meaning. The main effect is the difference in accuracy.

Of the data passed to the fragment shader, only the SV_POSITION semantic is necessary, which is used to store position information converted to clipping coordinates.

//Storage the information input by the vertex shader to the fragment shader
struct v2f
{ //Position information in the clipping space (SV_POSITION is required) float4 pos:SV_POSITION; float2 uv : TEXCOORD; //The semantics here mainly represent different precisions , TEXCOORD here only represents high precision, you can use COLOR semantics to represent low precision fixed4 color: TEXCOORD1; };





3. In the fragment shader, just mix the vertex color and the sampled texture and output it.

Sample code:

Shader"MyShader/P1_1_4"
{
    Properties
    {
        //命名要按标准来,这个属性才可以和Unity组件中的属性产生关联
        //比如说,在更改 Image 的源图片时,同时更改这个
        [PerRendererData]_MainTex("MainTex",2D) = "white"{}
        
        [PerRendererData]_Color("Color",color) = (1,1,1,1)
    }
    SubShader
    {
        //更改渲染队列(UI的渲染队列一般是半透明层的)
        Tags {"Queue" = "TransParent"}
        //混合模式
        Blend SrcAlpha OneMinusSrcAlpha
        Pass
        {
            CGPROGRAM
            #pragma vertex  vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            //存储 应用程序输入到顶点着色器的信息
            struct appdata
            {
                //顶点信息
                float4 vertex:POSITION;
                float2 uv : TEXCOORD;
                //这里定义一个语义为Color的4维向量,用于传入顶点颜色,设置语义为COLOR后,这个变量就会与顶点颜色对应
                fixed4 color:COLOR;
            };
            //存储 顶点着色器输入到片元着色器的信息
            struct v2f
            {
                //裁剪空间下的位置信息(SV_POSITION是必须的)
                float4 pos:SV_POSITION;
                float2 uv : TEXCOORD;
                //这里的语义主要代表精度不同,TEXCOORD 在这里只是代表高精度
                fixed4 color : TEXCOORD1;
            };
            
            sampler2D _MainTex;
            fixed4 _Color;
            v2f vert(appdata v)
            {
                v2f o;
                //把顶点信息转化到裁剪坐标下
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.color = v.color;
                return o;
            }
            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 mainTex = tex2D(_MainTex,i.uv);
                return  mainTex * i.color;
            }
            
            ENDCG
        }
    }
}

Effect (you can color the Shader by changing the color in the Image component of the UI):
Please add image description

Guess you like

Origin blog.csdn.net/qq_51603875/article/details/132958415