美文网首页Unity Shader
[Unity Shader] 遮罩Shader

[Unity Shader] 遮罩Shader

作者: m969 | 来源:发表于2019-01-20 19:30 被阅读0次

一、原理

遮罩shader的原理其实就是乘法运算
color * 1 = color
color * 0 = 0
在计算机程序语言表达颜色的时候,(1,1,1,1)表示白色和不透明,(0,0,0,0)表示黑色和完全透明
比如我们将color贴图和mask贴图(白色背景的可能看不见,可以点击放大)相乘,就会得到一个透明的彩色unity logo


color mask color_logo.png

二、实践

1、准备场景资源

首先我们分别新建一个表面着色器和材质,都命名为Mask,将shader赋予材质。
然后编辑shader代码,把无关的属性和代码都删掉,精简代码如下,只留一个主贴图属性:

Shader "Custom/Mask" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

我们在场景里新建一个Plane,赋上Mask材质,材质的Albedo贴图槽选择color贴图,现在材质的效果应该是这样的:


plane.png

2、增改shader代码

Shader "Custom/Mask" {
    Properties {
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _MaskTex("Mask", 2D) = "white" {} //add
    }
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Transparent"} //modified
        Blend SrcAlpha OneMinusSrcAlpha //add

        CGPROGRAM
        #pragma surface surf Standard keepalpha //modified
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MaskTex; //add

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            fixed4 m = tex2D (_MaskTex, IN.uv_MainTex); //add
            c = c * m; //add
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

这三句修改的代码都是为了让shader支持透明

        Tags { "RenderType"="Opaque" "Queue"="Transparent"} //modified
        Blend SrcAlpha OneMinusSrcAlpha //add
        #pragma surface surf Standard keepalpha //modified

最后我们把mask贴图拖进材质新增的Mask贴图槽


material.png

现在材质效果应该就是这样了:


color_logo.png

三、优化

但是通常我们用的mask贴图都不是透明贴图,而是黑白贴图。这是因为带透明通道的贴图消耗更高,而只要我们稍微改一下代码,黑白mask贴图可以实现和透明mask贴图完全一样的效果。
我们再将shader代码修改如下,仅需改一处代码:

Shader "Custom/Mask" {
    Properties{
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _MaskTex("Mask", 2D) = "white" {}
    }
        SubShader{
            Tags { "RenderType" = "Opaque" "Queue" = "Transparent"}
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma surface surf Standard keepalpha
            #pragma target 3.0

            sampler2D _MainTex;
            sampler2D _MaskTex;

            struct Input {
                float2 uv_MainTex;
            };

            void surf(Input IN, inout SurfaceOutputStandard o) {
                fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
                fixed4 m = tex2D(_MaskTex, IN.uv_MainTex);
                c = c * m.r; //modified
                o.Albedo = c.rgb;
                o.Alpha = c.a;
            }
            ENDCG
    }
        FallBack "Diffuse"
}
mask_black.png

然后我们再把透明mask贴图换成黑白的mask贴图,可以得到同样的遮罩效果。

结束

相关文章

网友评论

    本文标题:[Unity Shader] 遮罩Shader

    本文链接:https://www.haomeiwen.com/subject/ayfxjqtx.html