C for Graphic:遮挡透视

     最近刚好用上了这个效果所以记录一下,原理不再赘述,通过之前的透明原理和渲染队列详解就可以了解。遮挡透视可以区分为两部分,第一部分未被遮挡的顶点则正常栅格化着色,第二部分被遮挡的顶点则Ztest Greater(也就是判断当前顶点depth更大距离相机更远则栅格化着色),下面实现shader代码:

     

Shader "Unlit/OutrayShader"
{
    Properties
    {
        _OutlineColor("Outline Color",color) = (1,1,1,1)
		_RayColor("Ray Color",color) = (1,1,1,1)
		_OutScale("Outline Scale",Range(1,2)) = 1
		_RayScale("Ray Scale",Range(1,2)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Transparent" }
        LOD 100

		//正常渲染的outline
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
			};

			float4 _OutlineColor;		/*外描边颜色*/
			float _OutScale;

			//缩放矩阵
			static float4x4 _mats = float4x4(
				_OutScale, 0, 0, 0,
				0, _OutScale, 0, 0,
				0, 0, _OutScale, 0,
				0, 0, 0, 1
				);

			v2f vert(appdata v)
			{
				v2f o;
				//顶点缩放
				float4 vs = mul(_mats, v.vertex);
				o.vertex = UnityObjectToClipPos(vs);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				return _OutlineColor;
			}
			ENDCG
		}

		//透视着色
		Pass
		{
			//ztest greater时则渲染,也就是depth更大透视渲染
			ZTest Greater ZWrite off
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
			};

			float4 _RayColor;			/*透视颜色*/
			float _RayScale;

			static float4x4 _mats = float4x4(
				_RayScale, 0, 0, 0,
				0, _RayScale, 0, 0,
				0, 0, _RayScale, 0,
				0, 0, 0, 1
				);

			v2f vert(appdata v)
			{
				v2f o;
				//顶点缩放
				float4 vs = mul(_mats, v.vertex);
				o.vertex = UnityObjectToClipPos(vs);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				return _RayColor;
			}
			ENDCG
		}
    }
}

     效果如下:

  

  可以看得出来正常渲染红色,透视渲染绿色。

  当然了一般情况下我们的透视shader属于辅助着色功能,是在不影响原来美术调整好的着色效果情况下实现的第二层材质渲染,所以还得改一下,如下:

  

Shader "Custom/TransparencyShader"
{
    Properties
    {
		_RayColor("Ray Color",color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100

		//只需要透视渲染
        Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha
			ZTest Greater ZWrite off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
				float4 normal : NORMAL;
            };

            struct v2f
            {
				float3 worldp2v : TEXCOORD0;
				float3 worldn : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

			float4 _RayColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
				o.worldp2v = normalize(WorldSpaceViewDir(v.vertex));
				o.worldn = normalize(UnityObjectToWorldNormal(v.normal.xyz));
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				//边缘强度衰减
				float wei = saturate(dot(i.worldp2v,i.worldn));
				fixed4 col = fixed4(_RayColor.rgb, 1 - wei);
                return col;
            }
            ENDCG
        }
    }
}

     只对透视部分进行渲染,效果如下:

    

    差不多就得到遮挡透视渲染的效果了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值