Shader学习——透明测试,透明混合,深度写入半透明效果

核心命令

  • Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType" = "Transprent" }
    // 加入透明物体渲染队列,忽略投影器影响,提前归入组
  • ZWrite Off
    //关闭深度写入
  • Blend SrcAlpha OneMinusSrcAlpha
    //开启混合

效果图

透明测试,透明混合,深度写入半透明效果

透明测试

Shader "Unlit/016"
{
    Properties
    {
        _MainTex ("MainTex", 2D )= "white" {}
        _Diffuse("Diffuse",Color) = (1,1,1,1)
        _Cutoff("Alpha Cutoff",Range(0,1)) = 0.5
    }
    SubShader
    {
        Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" }
        LOD 100

        Pass
        {
            //定义光照流水线
            Tags{"LightMode" = "ForwardBase"}
            //关闭背面遮挡剔除
            Cull off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Diffuse;
            float _Cutoff;

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

            v2f vert (appdata_base v)
            {
                v2f o;
                //顶点位置
                o.vertex = UnityObjectToClipPos(v.vertex);
                //法线方向
                fixed3 worldNormal =UnityObjectToWorldNormal( v.normal);
                o.worldNormal=worldNormal;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                //UV =顶点纹理坐标进行缩放+偏移
                o.uv =TRANSFORM_TEX(v.texcoord, _MainTex);//v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {   
                //纹素值=对纹理进行采样(采样纹理,float2纹理坐标)
                fixed4 texColor = tex2D(_MainTex,i.uv);

                if((texColor.a - _Cutoff)<0)
                {
                    discard;
                }

                //光源方向
                fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
                //漫反射光=入射光线强度*纹素值*材质的漫反射系数*取值为正数(表面法线方向 · 光源方向)
                fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (dot(worldLightDir,i.worldNormal)*0.5+0.5);

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 color = ambient + diffuse ;

                return fixed4(color,1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

透明混合

Shader "Unlit/017"
{
    Properties
    {
        _MainTex ("MainTex", 2D )= "white" {}
        _Diffuse("Diffuse",Color) = (1,1,1,1)
        _AlphaScale("Alpha Scale", Range(0,1)) = 1
    }
    SubShader
    {
        Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType" = "Transprent" }
        LOD 100

        //关闭深度写入
        ZWrite Off
        //开启混合
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            //定义光照流水线
            Tags{"LightMode" = "ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Diffuse;
            float _AlphaScale;

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

            v2f vert (appdata_base v)
            {
                v2f o;
                //顶点位置
                o.vertex = UnityObjectToClipPos(v.vertex);
                //法线方向
                fixed3 worldNormal =UnityObjectToWorldNormal( v.normal);
                o.worldNormal=worldNormal;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                //UV =顶点纹理坐标进行缩放+偏移
                o.uv =TRANSFORM_TEX(v.texcoord, _MainTex);//v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {   
                //纹素值=对纹理进行采样(采样纹理,float2纹理坐标)
                fixed4 texColor = tex2D(_MainTex,i.uv);
                            
                //光源方向
                fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
                //漫反射光=入射光线强度*纹素值*材质的漫反射系数*取值为正数(表面法线方向 · 光源方向)
                fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (dot(worldLightDir,i.worldNormal)*0.5+0.5);

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 color = ambient + diffuse ;

                return fixed4(color,texColor.a * _AlphaScale);
            }
            ENDCG
        }
    }
    FallBack "Treansparent/VertexLit"
}

深度写入半透明效果

Shader "Unlit/018"
{
    Properties
    {
        _MainTex ("MainTex", 2D )= "white" {}
        _Diffuse("Diffuse",Color) = (1,1,1,1)
        _AlphaScale("Alpha Scale", Range(0,1)) = 1
    }
    SubShader
    {
        Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType" = "Transprent" }
        LOD 100

        pass
        {
            //开启深度写入
            ZWrite On
            //颜色遮罩,意味着不写入任何颜色通道
            ColorMask 0
        }
        

        Pass
        {
            //定义光照流水线
            Tags{"LightMode" = "ForwardBase"}
            
            //关闭深度写入
            ZWrite Off
            //开启混合
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Diffuse;
            float _AlphaScale;

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

            v2f vert (appdata_base v)
            {
                v2f o;
                //顶点位置
                o.vertex = UnityObjectToClipPos(v.vertex);
                //法线方向
                fixed3 worldNormal =UnityObjectToWorldNormal( v.normal);
                o.worldNormal=worldNormal;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                //UV =顶点纹理坐标进行缩放+偏移
                o.uv =TRANSFORM_TEX(v.texcoord, _MainTex);//v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {   
                //纹素值=对纹理进行采样(采样纹理,float2纹理坐标)
                fixed4 texColor = tex2D(_MainTex,i.uv);
                            
                //光源方向
                fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
                //漫反射光=入射光线强度*纹素值*材质的漫反射系数*取值为正数(表面法线方向 · 光源方向)
                fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (dot(worldLightDir,i.worldNormal)*0.5+0.5);

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 color = ambient + diffuse ;

                return fixed4(color,texColor.a * _AlphaScale);
            }
            ENDCG
        }
    }
    FallBack "Treansparent/VertexLit"
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Unity中两种方法实现透明效果: 1.透明度测试(Alpha Test),无法得到真正半透明效果,另外一种是透明...
    李偌闲阅读 4,097评论 0 0
  • 转载注明出处:点击打开链接 Shader(着色器)是一段能够针对3D对象进行操作、并被GPU所执行的程序。Shad...
    游戏开发小Y阅读 8,864评论 0 4
  • 透明度混合相较于透明度测试更加复杂一些,透明度混合可以得到真正的半透明效果,使用当前片元和透明度作为混合因子,与已...
    祝你万事顺利阅读 4,862评论 0 1
  • 关于 unity shader 的入门知识点网上还是有很多的,那这里进行一下简单的总结,当然只是对语法结构上的总结...
    一个有味道的名字阅读 7,768评论 1 4
  • 电影,本来打算两个人一起看的,享受两个人的美好时光,但是,后来多了一个人。三人行必有我师,有时候却会破坏了气氛。 ...
    芥空阅读 1,709评论 0 1