ngui 图片变灰Shader

原理

将彩色图片映射到灰度的的一个过程,我们一般使用的颜色值一般rgb32位每个八位的,在shader里面颜色被转换到[0-1]范围。根据人们的经验得到一个转换的比例是R:0.3 G:0.6 B:0.1 这个大概就是这个范围得到转换效果还不错。(有大神说过图像学第一定律就是看上去是对的,那它就是对的)

关键代码

fixed4 frag(v2f IN) : SV_Target
{
    fixed4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
    fixed valuergb = color.r * 0.3 + color.g * 0.6 + color.b * 0.1;
    color.rgb = valuergb;
    return color;
}

效果图

对于这个效果用在游戏ui上面还是不错的
ngui 图片变灰Shader_第1张图片

NGUI

对于ui我们用的是NGUI 打开NGUI 的UIWidget 发现NGUI的作者已经为自定义材质留好了接口,我们要改的是图片那么打开UISprite找到重写的这个方法加入自己的代码

/// 
    /// Custom material associated with the widget, if any.
    /// 

    public virtual Material material
    {
        get
        {
            return mMat;
        }
        set
        {
            if (mMat != value)
            {
                RemoveFromPanel();
                mMat = value;
                MarkAsChanged();
            }
        }
    }
     //uisprint更改
    /// 
    /// Material comes from the base class first, and sprite atlas last.
    /// 

    public bool isGray = false;
    protected Material grayMat;
    public override Material material
    {
        get
        {
            if(isGray)
            {
                if(grayMat == null)
                {
                    grayMat = new Material(Shader.Find("Unlit/Transparent ColoredGray"));
                }
                return grayMat;
            }
            else
            {
                var mat = base.material;
                if (mat != null) return mat;
                return (mAtlas != null ? mAtlas.spriteMaterial : null);
            }

        }
        set
        {
            base.material = value;
        }
    }

同时我们看到NGUI在Scroll View下面有一个裁剪效果而这个效果是替换了shader的也就是说我们要使得NGUI正常运行的话需要更改相关的shader。查看代码和NGUI自带shader复制4份,在每一个片段着色器进行一个灰度转换。注意shader的名称被裁减的是前面加了Hidden

//Shader "Hidden/Unlit/Transparent ColoredGray 1"
fixed4 frag (v2f IN) : SV_Target
{
   fixed4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
   col.rgb = col.r*0.3+col.g*0.6+col.b*0.1;
    return col;
}

ngui 图片变灰Shader_第2张图片
ngui 图片变灰Shader_第3张图片

最终效果图

ngui 图片变灰Shader_第4张图片

最后附上全部更改的Shader

其实就是加上了一句而且其他的都没有动
col.rgb = col.r*0.3+col.g*0.6+col.b*0.1;

Shader "Unlit/Transparent ColoredGray"
{
    Properties
    {
        _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
    }

    SubShader
    {
        LOD 200

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

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Fog { Mode Off }
            Offset -1, -1
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag           
            #include "UnityCG.cginc"

            // Unity 4 compatibility
            #ifndef UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_OUTPUT_STEREO
            #define UNITY_SETUP_INSTANCE_ID(v)
            #define UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(i)
            #define UnityObjectToClipPos(v) mul(UNITY_MATRIX_MVP, v)
            #endif

            sampler2D _MainTex;
            float4 _MainTex_ST;

            struct appdata_t
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                fixed4 color : COLOR;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                half2 texcoord : TEXCOORD0;
                fixed4 color : COLOR;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f o;

            v2f vert (appdata_t v)
            {
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = v.texcoord;
                o.color = v.color;
                return o;
            }

            fixed4 frag (v2f IN) : SV_Target
            {
               fixed4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
               col.rgb = col.r*0.3+col.g*0.6+col.b*0.1;
                return col;
            }
            ENDCG
        }
    }

}
Shader "Hidden/Unlit/Transparent ColoredGray 1"
{
    Properties
    {
        _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
    }

    SubShader
    {
        LOD 200

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

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Offset -1, -1
            Fog { Mode Off }
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            // Unity 4 compatibility
            #ifndef UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_OUTPUT_STEREO
            #define UNITY_SETUP_INSTANCE_ID(v)
            #define UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(i)
            #define UnityObjectToClipPos(v) mul(UNITY_MATRIX_MVP, v)
            #endif

            sampler2D _MainTex;
            float4 _ClipRange0 = float4(0.0, 0.0, 1.0, 1.0);
            float2 _ClipArgs0 = float2(1000.0, 1000.0);

            struct appdata_t
            {
                float4 vertex : POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                float2 worldPos : TEXCOORD1;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f o;

            v2f vert (appdata_t v)
            {
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = v.color;
                o.texcoord = v.texcoord;
                o.worldPos = v.vertex.xy * _ClipRange0.zw + _ClipRange0.xy;
                return o;
            }

            half4 frag (v2f IN) : SV_Target
            {
                // Softness factor
                float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos)) * _ClipArgs0;

                // Sample the texture
                half4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
                col.rgb = col.r*0.3+col.g*0.6+col.b*0.1;
                col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);
                return col;
            }
            ENDCG
        }
    }


}

Shader "Hidden/Unlit/Transparent ColoredGray 2"
{
    Properties
    {
        _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
    }

    SubShader
    {
        LOD 200

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

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Offset -1, -1
            Fog { Mode Off }
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            // Unity 4 compatibility
            #ifndef UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_OUTPUT_STEREO
            #define UNITY_SETUP_INSTANCE_ID(v)
            #define UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(i)
            #define UnityObjectToClipPos(v) mul(UNITY_MATRIX_MVP, v)
            #endif

            sampler2D _MainTex;
            float4 _ClipRange0 = float4(0.0, 0.0, 1.0, 1.0);
            float4 _ClipArgs0 = float4(1000.0, 1000.0, 0.0, 1.0);
            float4 _ClipRange1 = float4(0.0, 0.0, 1.0, 1.0);
            float4 _ClipArgs1 = float4(1000.0, 1000.0, 0.0, 1.0);

            struct appdata_t
            {
                float4 vertex : POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                float4 worldPos : TEXCOORD1;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            float2 Rotate (float2 v, float2 rot)
            {
                float2 ret;
                ret.x = v.x * rot.y - v.y * rot.x;
                ret.y = v.x * rot.x + v.y * rot.y;
                return ret;
            }

            v2f o;

            v2f vert (appdata_t v)
            {
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = v.color;
                o.texcoord = v.texcoord;
                o.worldPos.xy = v.vertex.xy * _ClipRange0.zw + _ClipRange0.xy;
                o.worldPos.zw = Rotate(v.vertex.xy, _ClipArgs1.zw) * _ClipRange1.zw + _ClipRange1.xy;
                return o;
            }

            half4 frag (v2f IN) : SV_Target
            {
                // First clip region
                float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos.xy)) * _ClipArgs0.xy;
                float f = min(factor.x, factor.y);

                // Second clip region
                factor = (float2(1.0, 1.0) - abs(IN.worldPos.zw)) * _ClipArgs1.xy;
                f = min(f, min(factor.x, factor.y));

                // Sample the texture
                half4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
                col.rgb = col.r*0.3+col.g*0.6+col.b*0.1;
                col.a *= clamp(f, 0.0, 1.0);
                return col;
            }
            ENDCG
        }
    }


}


Shader "Hidden/Unlit/Transparent ColoredGray 3"
{
    Properties
    {
        _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
    }

    SubShader
    {
        LOD 200

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

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Offset -1, -1
            Fog { Mode Off }
            //ColorMask RGB
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            // Unity 4 compatibility
            #ifndef UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_INPUT_INSTANCE_ID
            #define UNITY_VERTEX_OUTPUT_STEREO
            #define UNITY_SETUP_INSTANCE_ID(v)
            #define UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(i)
            #define UnityObjectToClipPos(v) mul(UNITY_MATRIX_MVP, v)
            #endif

            sampler2D _MainTex;
            float4 _ClipRange0 = float4(0.0, 0.0, 1.0, 1.0);
            float4 _ClipArgs0 = float4(1000.0, 1000.0, 0.0, 1.0);
            float4 _ClipRange1 = float4(0.0, 0.0, 1.0, 1.0);
            float4 _ClipArgs1 = float4(1000.0, 1000.0, 0.0, 1.0);
            float4 _ClipRange2 = float4(0.0, 0.0, 1.0, 1.0);
            float4 _ClipArgs2 = float4(1000.0, 1000.0, 0.0, 1.0);

            struct appdata_t
            {
                float4 vertex : POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                half4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                float4 worldPos : TEXCOORD1;
                float2 worldPos2 : TEXCOORD2;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            float2 Rotate (float2 v, float2 rot)
            {
                float2 ret;
                ret.x = v.x * rot.y - v.y * rot.x;
                ret.y = v.x * rot.x + v.y * rot.y;
                return ret;
            }

            v2f o;

            v2f vert (appdata_t v)
            {
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = v.color;
                o.texcoord = v.texcoord;
                o.worldPos.xy = v.vertex.xy * _ClipRange0.zw + _ClipRange0.xy;
                o.worldPos.zw = Rotate(v.vertex.xy, _ClipArgs1.zw) * _ClipRange1.zw + _ClipRange1.xy;
                o.worldPos2 = Rotate(v.vertex.xy, _ClipArgs2.zw) * _ClipRange2.zw + _ClipRange2.xy;
                return o;
            }

            half4 frag (v2f IN) : SV_Target
            {
                // First clip region
                float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos.xy)) * _ClipArgs0.xy;
                float f = min(factor.x, factor.y);

                // Second clip region
                factor = (float2(1.0, 1.0) - abs(IN.worldPos.zw)) * _ClipArgs1.xy;
                f = min(f, min(factor.x, factor.y));

                // Third clip region
                factor = (float2(1.0, 1.0) - abs(IN.worldPos2)) * _ClipArgs2.xy;
                f = min(f, min(factor.x, factor.y));

                // Sample the texture
                half4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
                col.rgb = col.r*0.3+col.g*0.6+col.b*0.1;
                col.a *= clamp(f, 0.0, 1.0);
                return col;
            }
            ENDCG
        }
    }


}

你可能感兴趣的:(ngui 图片变灰Shader)