前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shader-透明效果-透明度混合

Shader-透明效果-透明度混合

作者头像
祝你万事顺利
发布2019-05-28 23:12:27
2.1K0
发布2019-05-28 23:12:27
举报

透明度混合相较于透明度测试更加复杂一些,透明度混合可以得到真正的半透明效果,使用当前片元和透明度作为混合因子,与已经存储在颜色缓冲区的颜色值进行混合,得到新的颜色。透明度混合需要关闭深度写入,这使得我们需要关注物体的渲染顺序。 我们使用Unity的混合指令Blend,想实现半透明的效果就要把当前自身的颜色和已经存在的颜色缓冲中的颜色进行混合,混合时使用的函数就是该指令决定的。

ShaderLab Blend指令 Blend Off关闭混合 Blend SrcFactor DstFactor开启混合,并设置混合因子。源颜色乘SrcFactor,目标颜色乘以DstFactor,再将两者相加后存入颜色缓存中。

Blend.PNG

相较于透明度测试,代码部分改变,Tags的Queue标签设置为Transparent,RenderType标签让Shader归入提前定义的组,我们通过ZWriteOff关闭深度写入,Blend设置两个混合因子。 在fragment中,我们返回的的Color值包括一个Alpha值。

Shader "Unlit/AlphaBlend"
{
    Properties{
        _Color("Main 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"}
            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;
                    fixed3 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);
                    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);
                    fixed3 albedo = texColor.rgb * _Color.rgb;
                    fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
                    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT * albedo;
                    return fixed4(diffuse + ambient, texColor.a * _AlphaScale);
                }
                ENDCG
            }
        }
}

AplhaBlendTest.PNG

透明度混合的双面渲染 Cull Back是默认的,背对摄像机的一面不会被渲染 Cull Front 是面向摄像机的不会渲染

Pass{
                Tags{"LightMode" = "ForwardBase"}
                Cull Front
Pass{
                Tags{"LightMode" = "ForwardBase"}
                Cull Back

我们改动代码,先渲染背面,再渲染正面,可以得到下面的结果

AlphaBlendCull.PNG

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档