ShaderForge-遮罩效果

发表于2018-07-11
评论0 2.6k浏览
下面跟大家介绍的是遮罩效果的实现,在介绍之前,首先来了解下遮罩效果的实现原理。

遮罩效果



原理

最简单的方法就是制作一张带有预期的透明度值的遮罩图,我们依据遮罩图的透明度值来设置原图的透明度,就得到了遮罩效果。

透明度实现方式
在unity中实现透明度效果有两种方案,一种是透明度测试,一种是透明度混合。
- 透明度测试实现方式:既是片元的透明度和透明度阈值进行比较,小于这个透明度阈值的片元会直接被舍弃掉,不会做任何处理,相当于该片元透明。而大于这个透明度阈值的则会按照不透明的方式进行处理。
- 透明度混合实现方式:既是片元的透明度作为混合因子,片元的深度和深度缓冲区中的深度做比较,小于深度缓冲区中的深度时,片元的透明度不会与颜色缓冲区中的颜色进行混合,否则就会进行混合,最终片元的颜色会替换到颜色缓冲区中的颜色。

制作遮罩图

ShaderForge实现


手写unity shader实现

透明度测试
Shader "Custom/mask_u"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _MaskTex("Mask Texture", 2D) = "white" {}
    }
    SubShader
    {
        // 所有Pass中渲染队列使用透明度测试队列,渲染类型选择透明度测试类型,并且渲染过程中不受投影器的影响
        Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" }
        LOD 100
        Pass
        {
            Tags{ "LightModel" = "ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog
            #include "UnityCG.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _MaskTex;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                fixed4 mask_col = tex2D(_MaskTex, i.uv);
                // 进行透明度测试,小于透明度阈值的片元将会被舍弃,等价于 if ((mask_col.a - 0.5)) < 0.0) discard; 0.5是默认的透明度阈值
                clip(mask_col.a - 0.5);
                return col;
            }
            ENDCG
        }
    }
}

透明度混合
Shader "Custom/mask_u"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _MaskTex("Mask Texture", 2D) = "white" {}
    }
    SubShader
    {
        // 所有Pass中渲染队列使用透明度混合队列,渲染类型选择透明度混合类型,并且渲染过程中不受投影器的影响
        Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
        LOD 100
        Pass
        {
            Tags{ "LightModel" = "ForwardBase" }
            // 关闭深度写入,避免深度变化造成半透明异常
            ZWrite Off
            // 开启透明度混合,并设置片元颜色的乘积因子以及颜色缓冲区中颜色的乘积因子
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog
            #include "UnityCG.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _MaskTex;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                // 乘以遮罩图的透明度
                fixed4 mask_col = tex2D(_MaskTex, i.uv);
                col.a = col.a * mask_col.a;
                return col;
            }
            ENDCG
        }
    }
}
来自:https://blog.csdn.net/v_xchen_v/article/details/78473782

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引