使用透明度實現(xiàn)Mask遮罩的Unity Shader

原創(chuàng)文章,轉(zhuǎn)載請注明出處使用透明度實現(xiàn)Mask遮罩的Unity Shader

你好,用你的shader后在pc編輯器上是沒有問題的,在5.4環(huán)境下打包到手機上也沒問題,但是升級到5.5后打包到手機(ios,android的還沒試)上就顯示為粉紅色,不知道博主有沒有解決方案

感謝提醒,有時間我會修正一下

關于遮罩的需求

將矩形的圖片做成圓角矩形、圓形

常用實現(xiàn)方式

  1. 使用UGUI自帶的Mask組件實現(xiàn)
  2. 使用網(wǎng)上一搜一大把的簡單切割shader實現(xiàn)

存在的問題

這些實現(xiàn)方案容易出現(xiàn)鋸齒問題,見下圖

常見實現(xiàn)方案的鋸齒

鋸齒的由來

由于屏幕都是像素化的,所以看似圓滑的曲線,在屏幕上其實都是有鋸齒的,但由于人眼的識別能力有限,所以當鋸齒小到一定程度的時候就會認為曲線是圓滑的。
然而,由于分辨率問題,我們很難做到鋸齒足夠小,所以需要在產(chǎn)生鋸齒的邊緣添加顏色過渡,避免明顯的分界線,從而使人眼忽略鋸齒問題。

現(xiàn)有方案的鋸齒原因

由于現(xiàn)有方案是簡單的判斷遮罩的邊界:

  1. UGUI的Mask組件是通過透明度判斷,如果遮罩某像素點透明度達到一個值,則該像素點對應的顏色透明度不變,否則透明度置為0 ,使用遮罩的透明度作為掩碼寫入緩沖區(qū),之后只渲染緩沖區(qū)為1的區(qū)域。
    以下為官方文檔說明

Implementation

Masking is implemented using the stencil buffer of the GPU.
*The first Mask element writes a 1 to the stencil buffer *
All elements below the mask check when rendering, and only render to areas where there is a 1 in the stencil buffer
Nested Masks will write incremental bit masks into the buffer, this means that renderable children need to have the logical & of the stencil values to be rendered.

  1. 簡單切割shader的實現(xiàn)是通過邊緣檢測來判斷該點是否顯示,不顯示則透明度置為0

發(fā)現(xiàn)了嗎,這些方案都是非黑即白的的方案,根本實現(xiàn)不了顏色過渡,所以存在鋸齒的現(xiàn)象

解決方案

我給出的方案是使用透明度疊加來做

1.制作一張PS做的帶透明度過渡的遮罩
2.編寫shader,獲取這張遮罩的透明度,將該透明度和目標圖片的透明度進行混合

效果

使用遮罩前
制作材質(zhì)球
添加材質(zhì)球
使用遮罩后
其他形狀的遮罩

shader代碼

Shader "ImageEffect/MaskIcon" 
{  
    Properties 
    {  
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Mask ("Base (RGB)", 2D) = "white" {}  


        _Color ("Tint", Color) = (1,1,1,1)
        _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
    }
    
    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
            
            #include "UnityCG.cginc"
            #include "UnityUI.cginc"
            
            #pragma multi_compile __ UNITY_UI_ALPHACLIP

            struct a2v
            {
                fixed2 uv : TEXCOORD0;
                half4 vertex : POSITION;
                float4 color    : COLOR;
            };

            fixed4 _Color;

            struct v2f
            {
                fixed2 uv : TEXCOORD0;
                half4 vertex : SV_POSITION;
                float4 color    : COLOR;
            };

            sampler2D _MainTex;
            sampler2D _Mask;  

            v2f vert (a2v i)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, i.vertex);
                o.uv = i.uv;

                o.color = i.color * _Color;
                return o;
            }
            
            fixed4 frag (v2f i) : COLOR
            {
                half4 color = tex2D(_MainTex, i.uv) * i.color; 
                half4 mask = tex2D(_Mask, i.uv); 
                color.a *= mask.a;
                return color;
            }
            ENDCG
        }  
    }   
}  
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容