小小千想和您聊一聊

当前位置: 首页> 技术分享> Unity着色器特效之遮挡渲染

Unity着色器特效之遮挡渲染

  Unity开发到一定阶段,Shader是一个不得不接触的东西,很多东西也确确实实只能用Shader去解决,C#是解决不了的。虽然这两年绝地求生是热度有些下滑,但还是有很多职业选手参与比赛,这其中就有我们熟知的韦神之类的。但在观看赛事时,我们从解说的视角来看,似乎所有的人,我们都能看到,想开了透视外挂,只是在障碍物后的人物渲染的方式有些不同,那这种被遮挡后还能看到,且换了一种渲染方式的功能是怎么去实现的呢?接下来我们就来详细看看,其实没那么复杂。

  首先,我们先要了解Shader中通道(Pass)的概念,通道指的是画面渲染的最终执行内容,一般情况下,Shader是使用单通道的,但如果遇到渲染是需要条件限制,或特殊渲染,此时则需要多通道。当然渲染通道越多,渲染所消耗的性能越大。

  实现遮挡特效的原理很简单,只需要判断角色是否被其他物体所遮挡,如果没有被遮挡了,则用通道1去渲染;如果被遮挡了就用通道2去渲染。那么问题来了,如何判断角色被遮挡了呢?

  在ShaderLab中有深度测试的命令(ZTest),可以测试当前顶点在渲染时的深度,当然测试之后就可以产生对比,在ZTest后面可以添加对比的关键词,如大于(Greater),小于(Less),大于等于(GEqual),小于等于(LEqual)等。

  也就是说如果ZTest Greater,那么说明当前对象的深度更大,也就是距离摄像机更远,即被遮挡,反之ZTest LEqual说明当前深度小,没被遮挡。当然这里非常重要的一点是,先要判断ZTest Greater的时候,要关闭深度缓存ZWrite,从而保证后面的Pass可以覆盖当前Pass的渲染。具体代码如下:

SubShader 
{
        
		  ZWrite Off
		  //先判断Greater,因此此Pass必须放在第一个
        Pass
        {
            ZTest Greater
            Color(1,0,0,1)
        }
        
        Pass
        {
            ZTest LEqual
            Color(0,1,0,1)
        }
}

  此时,我们看到方块在正常渲染的时候渲染为绿色,当被遮挡的时候,渲染成红色,从而达成遮挡渲染,即透视。当然,上例,使用的固定管线渲染,灵活度比较差,接下来我们来看顶点片段的代码:

Shader "Custom/Demo" {
    Properties {
        _MainTex ("Main Tex", 2D) = "white" {}
        _OcclusionColor("OcclusionColor",Color)=(0.5,1,0.5,1)
    }
    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        //先判断Greater,因此此Pass必须放在第一个
        Pass
        {
            ZTest Greater
	         ZWrite Off
            CGPROGRAM
            #pragma vertex vert 
            #pragma fragment frag
            fixed4 _OcclusionColor;
            float4 vert(float4 v : POSITION) : SV_POSITION {
                return UnityObjectToClipPos(v);
            }
            fixed4 frag() : SV_Target{
                return _OcclusionColor;
            }
            ENDCG
        }
        
        
        Pass
        {
            ZTest LEqual
            Tags { "LightMode"="ForwardBase" }
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Lighting.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;
            struct a2v {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
            };
            
            struct v2f {
                float4 position : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            
            v2f vert(a2v v) {
                v2f o; 
                o.position = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); 
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target {
                fixed4 c = tex2D(_MainTex, i.uv);
                return fixed4(c.rgb, 1.0);
            }
            
            ENDCG
        }
    }
    FallBack "Diffuse"
}

  到此,我们就完成了遮挡特效的Shader,顶点片段层面下,大家可以设置自己想要的渲染效果,法线、高光、边缘光等。包括遮挡时,也可以设置稍微酷炫一些的特效。小伙伴们,你们学会了吗?

上一篇:跨域

下一篇:快速搭建一个AR

QQ技术交流群

千锋Unity开发官方①群
858321642

加入群聊

用户登录

手机号:

密码:

图形验证码:

点击切换

用户注册

手机号:

登录密码:

图形验证码:

点击切换

短信验证码:

获取验证码

忘记密码

1安全验证

2重置密码

手机号:

图形验证码:

短信验证码:

获取验证码

忘记密码

1安全验证

2重置密码

新密码:

确认新密码:

获取课程

添加小千老师微信,获取课程信息

如何获取课程?

一、需拥有此本教材

如没有,可点击下方入口购买当当购买入口京东购买入口

二、添加小千老师,发送拥有凭证,解锁课程资源

1.购买该教材的订单信息
2.拥有的实体书信息等

更换手机号

新手机号:

图形验证码:

短信验证码:

获取验证码