《Unity Shader 入门精要》读书笔记—透明度混合

《Unity Shader 入门精要》读书笔记—透明度混合

综述

在我阅读过的文献中,我了解到两种模拟透明度的方法,一种是基于checkerboard遮罩的透明效果,另一种是基于透明度混合的透明效果。
checkerboard的原理类似于人们穿着的薄纱,而透明度混合基于的是纯粹的色彩调和。

Unity Shader与透明度混合

当我们想要在Unity Shader中实现透明度混合效果,那么我们可能会用到如下命令:

语义 描述
Blend Off 关闭混合
Blend SrcFactor DstFactor 开启混合并设置混合因子
Blend SrcFactor DstFactor,SrcFactorA DstFactorA 类似于上一个,单独处理了Alpha通道
BlendOp BlendOperation 使用BlendOperation进行自定义处理

本节使用了表里第二种方法,则得到的颜色为:
D s t C o l o r n e w = S r c A l p h a × S r c C o l o r + ( 1 − S r c A l p h a ) × D s t C o l o r o l d DstColor_{new}=SrcAlpha\times SrcColor+(1-SrcAlpha)\times DstColor_{old} DstColornew=SrcAlpha×SrcColor+(1SrcAlpha)×DstColorold

实现

Shader "Unity Shaders Book/Chapter 8/Alpha Blend"{
    Properties{
        _Color ("Color Tint",Color)=(1,1,1,1)
        _MainTex ("Main Tex",2D)="white" {}
        _AlphaScale ("Alpha Scale",Range(0,1))=1
    }

    SubShader{
        Tags{"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}//开启透明度混合队列,忽略投影影响,将此shader归入transparent组中(此处为一般设置)

        pass{
            Tags{"LightMode"="ForwardBase"}
            //设置混合状态
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            fixed4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed _AlphaScale;

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

            struct v2f{
                float4 pos:SV_POSITION;
                float3 worldNormal:TEXCOORD0;
                float3 worldPos:TEXCOORD1;
                float2 uv:TEXCOORD2;
            };

            v2f vert(a2v v){
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.worldNormal=UnityObjectToWorldNormal(v.normal);
                o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
                o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);

                return o;
            }

            fixed4 frag(v2f i):SV_TARGET{
                fixed3 worldNormal=normalize(i.worldNormal);
                fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));

                fixed4 texColor=tex2D(_MainTex,i.uv.xy);

                fixed3 albedo=texColor.rgb*_Color.rgb;
                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
                fixed3 diffuse=_LightColor0.rgb*albedo*max(0,dot(worldLightDir,worldNormal));
                return fixed4(ambient+diffuse,texColor.a*_AlphaScale);//设置混合透明度
            }
            ENDCG
        }
    }
    Fallback "Transparent/VertexLit"
}

最终效果如下:
《Unity Shader 入门精要》读书笔记—透明度混合_第1张图片
由于我们关闭了深度写入,那么较为复杂的透明物体可能产生不正确的效果:
《Unity Shader 入门精要》读书笔记—透明度混合_第2张图片

你可能感兴趣的:(Unity,Shader)