U3DC.COM | 优三帝研究院

Menu

Unity Shader开发之 Blend(混合)

1.什么是Blend

如其英文所示,就是混合的意思。表示:在物体重叠时,不同的游戏对象之间的色彩混合方式。

公式:(Shader计算出的点颜色值 源系数)+ (点累积颜色 * 目标系数)

2.Blend的多种混合类型:

(1)Blend One One(线性减淡)

粒子常用,如火焰粒子。

(2)Blend SrcAlpha OneMinusSrcAlpha(透明混合)

正常的透明效果。

(3)Blend OneMinusDstColor One(滤色)

(4)Blend DstColor Zero(正片叠底)

(5)Blend DstColor SrcColor(类似X光片效果)

(6)Blend One OneMinusSrcAlpha(透明度混合)

当前颜色 x 当前透明度 +(1 - 当前透明度)x 缓存颜色

3.示例代码

Shader "Unlit/AlphaBlend"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _AlphaScale  ("AlphaScale" , Range(0 , 1)) = 1.0      //用于在透明纹理的基础上控制整体的透明度
    }
    SubShader
    {
        Tags 
        { 
            "Queue" = "Transparent"             //渲染队列3000
            "IgnoreProjector" = "True"          //shader不会受到投影器(Projectors)的影响
            "RenderType" = "Transparent"        //把Shader归入到提前定义的组(这里是Transparent组)
                                                //以指明该Shader使用了透明度混合
                                                //RenderType标签通常被用于着色器替换功能
        }

        //pass1
        pass
        {
            //渲染状态
            ZWrite On       //开启深度写入
            ColorMask 0     //不写入颜色缓冲区
        }

        //pass2
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            //渲染状态
            ZWrite Off                              //必须关闭深度写入
            Blend srcAlpha OneMinusSrcAlpha         //设置混合模式
                                                    //源颜色的混合因子设为 srcAlpha
                                                    //目标颜色(颜色缓冲区)的混合因子设为 OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            //定义属性
            uniform sampler2D _MainTex;
            uniform float4    _MainTex_ST;
            uniform fixed     _AlphaScale;          

            struct a2v
            {
                float4 vertex : POSITION;
                float2 uv0    : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv0    : TEXCOORD0;
                float3 nDirWS : TEXCOORD1;
                float4 posWS  : TEXCOORD2;
            };


            v2f vert (a2v v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv0    = v.uv0 * _MainTex_ST.xy + _MainTex_ST.zw;
                o.nDirWS = UnityObjectToWorldDir(v.normal);
                o.posWS  = mul(unity_ObjectToWorld , v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 nDirWS = normalize(i.nDirWS);
                fixed3 lDirWS = normalize(UnityWorldSpaceLightDir(i.posWS));
                fixed4 var_MainTex = tex2D(_MainTex , i.uv0);

                fixed  lambert = max(0.0 , dot(nDirWS , lDirWS));
                fixed3 albedo = var_MainTex.rgb ;
                fixed3 diffuse = albedo *_LightColor0.rbg * lambert;
                return fixed4(diffuse , var_MainTex.a * _AlphaScale);
            }         
            ENDCG
        }
    }
    Fallback "Transparent/VertexLit"
}
打赏
— 于 共写了1792个字
— 文内使用到的标签:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据