UI shader图片效果处理

本文介绍了如何使用Unity的Shader进行图片处理,包括调节图片亮度、饱和度和对比度,以及实现边缘检测和高斯模糊效果。通过自定义Shader,可以实时改变图片的视觉效果,如动态灰度、边缘突出和模糊处理。文章提供了详细的Shader代码示例,展示了不同效果的对比。
摘要由CSDN通过智能技术生成

图片处理

unity 可以直接写shader对图片处理,调节图片的 亮度,饱和度,对比度



前言

有时需要对动态图片进行处理达到一些效果,就像照片美图处理


一、图片调节

图片需要变成灰色,颜色要更饱和等

二、Unity 中的shader 实现

1. 亮度,饱和度,对比度

代码如下(示例):

Shader “Unlit/ColorBlending”
{
Properties
{
_MainTex (“Texture”, 2D) = “white” {}
_Brightness(“亮度:”,Range(0.1,2))=1
_Saturation(“饱和度:”,Range(0,2))=1//±20
_Contrast(“对比度:”,Range(0.1,5))=1
}
SubShader
{
Tags { “RenderType”=“Opaque” }
LOD 100

    Pass
    {
         ZTest Always Cull Off ZWrite Off
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
      
        #include "UnityCG.cginc"
  
        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
           
            float4 vertex : SV_POSITION;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        half _Brightness;
        half _Saturation;
        half _Contrast;

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);
           
            return o;
        }

        fixed4 frag (v2f i) : SV_Target
        {
            // sample the texture
            fixed4 col = tex2D(_MainTex, i.uv);
            
        fixed3 finalColor = col.rgb * _Brightness;
        fixed lum = 0.2125 * col.r + 0.7154 * col.g + 0.0721 * col.b;
        fixed3 lumColor = fixed3(lum, lum, lum);
        finalColor = lerp(lumColor, finalColor, _Saturation);

        fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
        finalColor = lerp(avgColor, finalColor, _Contrast);

            return fixed4(finalColor,col.a);
        }
        ENDCG
    }
}

}

2.效果对比

在这里插入图片描述
在这里插入图片描述


二、边缘检测

这是直接在处理UI里的图片,调整数值就可以达到边缘检测的效果图片;

Shader "Unlit/EdgeDetection"
{
    Properties
    {
       _MainTex("Texture", 2D) = "white" {}
            _EdgeOnly("边缘化:", Range(0,4)) = 1.0
            _EdgeColor("边缘颜色:", Color) = (0,0,0,1)
            _BackgroundColor("背景颜色:",Color) = (1,1,1,0)
            _Thickness("权重:",Range(0,4)) = 1.0
            _Speed("Speed",Range(-1,0)) = -0.5
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Transparent"}
        LOD 100
              Pass
                {
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #include "UnityCG.cginc"

                    struct appdata
                    {
                        float4 vertex : POSITION;
                        float2 uv : TEXCOORD0;
                    };

                    struct v2f
                    {
                        float2 uv : TEXCOORD0;
                        float4 vertex : SV_POSITION;
                    };

                    sampler2D _MainTex;
                    float4 _MainTex_ST;

                    v2f vert(appdata v)
                    {
                        v2f o;
                        o.vertex = UnityObjectToClipPos(v.vertex);
                        o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                        return o;
                    }

                    fixed4 frag(v2f i) : SV_Target
                    {
                        fixed4 col = tex2D(_MainTex, i.uv);
                    /* UNITY_APPLY_FOG(i.fogCoord, col);*/
                     return col;
                 }
                 ENDCG
             }
    Pass
                {
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag

                    #include "UnityCG.cginc"

                    struct appdata
                    {
                        float4 vertex : POSITION;
                        float2 uv : TEXCOORD0;
                    };

                    struct v2f
                    {
                        float2 maskuv : TEXCOORD0;
                        float2 uv[9] : TEXCOORD1;
                        float4 vertex : SV_POSITION;
                    };

                    sampler2D _MainTex;
                    sampler2D _MaskTex;
                    half4 _MainTex_TexelSize;
                    fixed _EdgeOnly;
                    fixed4 _EdgeColor;
                    fixed4 _BackgroundColor;
                    fixed _Thickness;
                    fixed _Speed;

                    fixed luminance(fixed4 color)
                    {
                        return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;
                    }

                    half Sobel(v2f i)
                    {
                        const half Gx[9] = {-1,-2,-1,0,0,0,1,2,1};
                        const half Gy[9] = { -1,0,1,-2,0,2,-1,0,1 };

                        half texColor;
                        half edgeX = 0;
                        half edgeY = 0;
                        for (int it = 0; it < 9; it++)
                        {
                            texColor = luminance(tex2D(_MainTex, i.uv[it]));
                            edgeX += texColor * Gx[it];
                            edgeY += texColor * Gy[it];
                        }

                        half edge = 1 - abs(edgeX) - abs(edgeY);
                        return edge;
                    }

                    v2f vert(appdata v)
                    {
                        v2f o;
                        o.vertex = UnityObjectToClipPos(v.vertex);

                        half2 uv = v.uv;

                        o.maskuv = v.uv - frac(fixed2(0,_Speed * _Time.y));
                        //o.maskuv = v.uv + fixed2(0.7 * _Time.y,0);

                        o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-1, -1) * _Thickness;
                        o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1) * _Thickness;
                        o.uv[2] = uv + _MainTex_TexelSize.xy * half2(1, -1) * _Thickness;
                        o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1, 0) * _Thickness;
                        o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0) * _Thickness;
                        o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, 0) * _Thickness;
                        o.uv[6] = uv + _MainTex_TexelSize.xy * half2(-1, 1) * _Thickness;
                        o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1) * _Thickness;
                        o.uv[8] = uv + _MainTex_TexelSize.xy * half2(1, 1) * _Thickness;

                        return o;
                    }

                    fixed4 frag(v2f i) : SV_Target
                    {
                        half edge = Sobel(i);

                        fixed4 maskColor = tex2D(_MaskTex, i.maskuv);

                        fixed4 withEdgeColor = lerp(_EdgeColor,tex2D(_MainTex, i.uv[4]),edge);
                        fixed4 onlyEdgeColor = lerp(_EdgeColor, _BackgroundColor, edge);

                        fixed4 col = lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly);
                        return fixed4(col.rgb,col.a * (1 - maskColor.r));
                    }
                    ENDCG
                }
    }
            Fallback off
}

2.效果对比

在这里插入图片描述
在这里插入图片描述

三、高斯模糊

1.目前效果一般,但是还能用

 Shader "Custom/MaskedUIBlur" {
        Properties{
            _Size("Blur", Range(0, 60)) = 1
            [HideInInspector]
            _MainTex("Masking Texture", 2D) = "white" {}
            [HideInInspector]
            _AdditiveColor("Additive Tint color", Color) = (0, 0, 0, 0)
            _MultiplyColor("Multiply Tint color", Color) = (1, 1, 1, 1)
        }

            Category{

                // We must be transparent, so other objects are drawn before this one.

               Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }

                SubShader
                {
                    // Horizontal blur
                    GrabPass
                    {
                        "_HBlur"
                    }
 
                Cull Off
                Lighting Off
                ZWrite Off
                ZTest[unity_GUIZTestMode]
                Blend SrcAlpha OneMinusSrcAlpha

                Pass
                {
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma fragmentoption ARB_precision_hint_fastest
                    #include "UnityCG.cginc"

                    struct appdata_t {
                        float4 vertex : POSITION;
                        float2 texcoord : TEXCOORD0;
                    };

                    struct v2f {
                        float4 vertex : POSITION;
                        float4 uvgrab : TEXCOORD0;
                        float2 uvmain : TEXCOORD1;
                    };

                    sampler2D _MainTex;
                    float4 _MainTex_ST;

                    v2f vert(appdata_t v)
                    {
                        v2f o;
                        o.vertex = UnityObjectToClipPos(v.vertex);

                        #if UNITY_UV_STARTS_AT_TOP
                        float scale = -1.0;
                        #else
                        float scale = 1.0;
                        #endif

                        o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
                        o.uvgrab.zw = o.vertex.zw;

                        o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
                        return o;
                    }

                    sampler2D _HBlur;
                    float4 _HBlur_TexelSize;
                    float _Size;
                    float4 _AdditiveColor;
                    float4 _MultiplyColor;

                    half4 frag(v2f i) : COLOR
                    {
                        half4 sum = half4(0,0,0,0);

                        #define GRABPIXEL(weight,kernelx) tex2Dproj( _HBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x + _HBlur_TexelSize.x * kernelx * _Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight

                        sum += GRABPIXEL(0.05, -4.0);
                        sum += GRABPIXEL(0.09, -3.0);
                        sum += GRABPIXEL(0.12, -2.0);
                        sum += GRABPIXEL(0.15, -1.0);
                        sum += GRABPIXEL(0.18,  0.0);
                        sum += GRABPIXEL(0.15, +1.0);
                        sum += GRABPIXEL(0.12, +2.0);
                        sum += GRABPIXEL(0.09, +3.0);
                        sum += GRABPIXEL(0.05, +4.0);


                        half4 result = half4(sum.r * _MultiplyColor.r + _AdditiveColor.r,
                                            sum.g * _MultiplyColor.g + _AdditiveColor.g,
                                            sum.b * _MultiplyColor.b + _AdditiveColor.b,
                                            tex2D(_MainTex, i.uvmain).a * _Size);
                        return result;
                    }
                    ENDCG
                }

                // Vertical blur
                GrabPass
                {
                    "_VBlur"
                }

                Pass
                {
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma fragmentoption ARB_precision_hint_fastest
                    #include "UnityCG.cginc"

                    struct appdata_t {
                        float4 vertex : POSITION;
                        float2 texcoord: TEXCOORD0;
                    };

                    struct v2f {
                        float4 vertex : POSITION;
                        float4 uvgrab : TEXCOORD0;
                        float2 uvmain : TEXCOORD1;
                    };

                    sampler2D _MainTex;
                    float4 _MainTex_ST;

                    v2f vert(appdata_t v) {
                        v2f o;
                        o.vertex = UnityObjectToClipPos(v.vertex);

                        #if UNITY_UV_STARTS_AT_TOP
                        float scale = -1.0;
                        #else
                        float scale = 1.0;
                        #endif

                        o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
                        o.uvgrab.zw = o.vertex.zw;

                        o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);

                        return o;
                    }

                    sampler2D _VBlur;
                    float4 _VBlur_TexelSize;
                    float _Size;
                    float4 _AdditiveColor;
                    float4 _MultiplyColor;

                    half4 frag(v2f i) : COLOR
                    {
                        half4 sum = half4(0,0,0,0);

                        #define GRABPIXEL(weight,kernely) tex2Dproj( _VBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _VBlur_TexelSize.y * kernely * _Size, i.uvgrab.z, i.uvgrab.w))) * weight

                        sum += GRABPIXEL(0.05, -4.0);
                        sum += GRABPIXEL(0.09, -3.0);
                        sum += GRABPIXEL(0.12, -2.0);
                        sum += GRABPIXEL(0.15, -1.0);
                        sum += GRABPIXEL(0.18,  0.0);
                        sum += GRABPIXEL(0.15, +1.0);
                        sum += GRABPIXEL(0.12, +2.0);
                        sum += GRABPIXEL(0.09, +3.0);
                        sum += GRABPIXEL(0.05, +4.0);

                        half4 result = half4(sum.r * _MultiplyColor.r + _AdditiveColor.r,
                                            sum.g * _MultiplyColor.g + _AdditiveColor.g,
                                            sum.b * _MultiplyColor.b + _AdditiveColor.b,
                                            tex2D(_MainTex, i.uvmain).a * _Size);
                        return result;
                    }
                    ENDCG
                }

//可重复
                    Pass
                    {
                        CGPROGRAM
                        #pragma vertex vert
                        #pragma fragment frag
                        #pragma fragmentoption ARB_precision_hint_fastest
                        #include "UnityCG.cginc"

                        struct appdata_t {
                            float4 vertex : POSITION;
                            float2 texcoord : TEXCOORD0;
                        };

                        struct v2f {
                            float4 vertex : POSITION;
                            float4 uvgrab : TEXCOORD0;
                            float2 uvmain : TEXCOORD1;
                        };

                        sampler2D _MainTex;
                        float4 _MainTex_ST;

                        v2f vert(appdata_t v)
                        {
                            v2f o;
                            o.vertex = UnityObjectToClipPos(v.vertex);

                            #if UNITY_UV_STARTS_AT_TOP
                            float scale = -1.0;
                            #else
                            float scale = 1.0;
                            #endif

                            o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
                            o.uvgrab.zw = o.vertex.zw;

                            o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
                            return o;
                        }

                        sampler2D _HBlur;
                        float4 _HBlur_TexelSize;
                        float _Size;
                        float4 _AdditiveColor;
                        float4 _MultiplyColor;

                        half4 frag(v2f i) : COLOR
                        {
                            half4 sum = half4(0,0,0,0);

                            #define GRABPIXEL(weight,kernelx) tex2Dproj( _HBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x + _HBlur_TexelSize.x * kernelx * (_Size*1.2), i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight

                            sum += GRABPIXEL(0.05, -4.0);
                            sum += GRABPIXEL(0.09, -3.0);
                            sum += GRABPIXEL(0.12, -2.0);
                            sum += GRABPIXEL(0.15, -1.0);
                            sum += GRABPIXEL(0.18,  0.0);
                            sum += GRABPIXEL(0.15, +1.0);
                            sum += GRABPIXEL(0.12, +2.0);
                            sum += GRABPIXEL(0.09, +3.0);
                            sum += GRABPIXEL(0.05, +4.0);


                            half4 result = half4(sum.r * _MultiplyColor.r + _AdditiveColor.r,
                                                sum.g * _MultiplyColor.g + _AdditiveColor.g,
                                                sum.b * _MultiplyColor.b + _AdditiveColor.b,
                                                tex2D(_MainTex, i.uvmain).a * (_Size * 1.2));
                            return result;
                        }
                        ENDCG
                    }

                        Pass
                        {
                            CGPROGRAM
                            #pragma vertex vert
                            #pragma fragment frag
                            #pragma fragmentoption ARB_precision_hint_fastest
                            #include "UnityCG.cginc"

                            struct appdata_t {
                                float4 vertex : POSITION;
                                float2 texcoord: TEXCOORD0;
                            };

                            struct v2f {
                                float4 vertex : POSITION;
                                float4 uvgrab : TEXCOORD0;
                                float2 uvmain : TEXCOORD1;
                            };

                            sampler2D _MainTex;
                            float4 _MainTex_ST;

                            v2f vert(appdata_t v) {
                                v2f o;
                                o.vertex = UnityObjectToClipPos(v.vertex);

                                #if UNITY_UV_STARTS_AT_TOP
                                float scale = -1.0;
                                #else
                                float scale = 1.0;
                                #endif

                                o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
                                o.uvgrab.zw = o.vertex.zw;

                                o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);

                                return o;
                            }

                            sampler2D _VBlur;
                            float4 _VBlur_TexelSize;
                            float _Size;
                            float4 _AdditiveColor;
                            float4 _MultiplyColor;

                            half4 frag(v2f i) : COLOR
                            {
                                half4 sum = half4(0,0,0,0);

                                #define GRABPIXEL(weight,kernely) tex2Dproj( _VBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _VBlur_TexelSize.y * kernely * (_Size*1.2), i.uvgrab.z, i.uvgrab.w))) * weight

                                sum += GRABPIXEL(0.05, -4.0);
                                sum += GRABPIXEL(0.09, -3.0);
                                sum += GRABPIXEL(0.12, -2.0);
                                sum += GRABPIXEL(0.15, -1.0);
                                sum += GRABPIXEL(0.18,  0.0);
                                sum += GRABPIXEL(0.15, +1.0);
                                sum += GRABPIXEL(0.12, +2.0);
                                sum += GRABPIXEL(0.09, +3.0);
                                sum += GRABPIXEL(0.05, +4.0);

                                half4 result = half4(sum.r * _MultiplyColor.r + _AdditiveColor.r,
                                                    sum.g * _MultiplyColor.g + _AdditiveColor.g,
                                                    sum.b * _MultiplyColor.b + _AdditiveColor.b,
                                                    tex2D(_MainTex, i.uvmain).a * (_Size * 1.2));
                                return result;
                            }
                            ENDCG
                        }

            }
            }
    }
    //重复结束

重复 Pass 修改_Size值,重复次数越多效果越佳,只是运行越大

2.效果对比

在这里插入图片描述

总结

参考部分忘了保存链接,对参考大神说声谢谢!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值