Unity3D Shader 之透视效果XRay

发布时间:2024年01月04日

1、

Shader "Unlit/XRay"
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {}

	// 漫反射
	_Diffuse("Diffuse", COLOR) = (1,1,1,1)



		// XRay 效果
		_XRayColor("XRay Color", COLOR) = (0,1,1,1)
		_XRayPower("XRay Power", Range(0.00001,3)) = 0.001
	}
		SubShader
	{
		Tags { "Queue" = "Geometry+1000" "RenderType" = "Opaque" }
		LOD 100




		Pass
		{
		Stencil {
				Ref 254
				Comp Always
				Pass Replace
				ZFail Keep
			}

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag


			#include "UnityCG.cginc"
			#include "Lighting.cginc"



			struct v2f
			{

				float4 vertex : SV_POSITION;
		float2 uv : TEXCOORD0;
		float3 worldNormal:TEXCOORD1;
		float3 worldPos:TEXCOORD2;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float4 _Diffuse;
		float _Steps;
		float _ToonLerpWeight;
		float4 _RimColor;
		float _RimPower;

			v2f vert(appdata_base v)
			{
				v2f o;
				o.vertex = 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
			{
				// 环境光
				float3 ambient = UNITY_LIGHTMODEL_AMBIENT;

				// 贴图的本色
				fixed3 albedo = tex2D(_MainTex, i.uv).rgb;

				// 视野方向
				float3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));

				// 漫反射
				fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
				float halfLambert = dot(worldLightDir,i.worldNormal) * 0.5 + 0.5;

				// 最终漫反射
				fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * halfLambert;

				return fixed4(ambient + diffuse,1);
			}
			ENDCG
		}

		Pass{
			Tags{"ForceNoShadowCasting" = "true"}

			Name "XRay"

				// 添加 混合效果 注意渲染顺序 Queue
				Blend SrcAlpha one

				// 关闭深度写入
				ZWrite off
				ZTest Greater  // 表示大于的时候显示(目的显示墙后面的物体)

				//使用Stencil进行过滤,该Shader的第一个Pass中我们向Stencil Buffer中写入一个值254,在Xray的pass中,如果stencil的值为254,则不再绘制效果
				Stencil {
					Ref 254
					Comp NotEqual
					Pass Keep
					ZFail Keep
				}


				CGPROGRAM

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

				float4 _XRayColor;
				float _XRayPower;
				struct v2f {
					float4 vertex :SV_POSITION;

					//方法一,得到世界点,再到片元中计算视野方向
					//float3 worldPos:TEXCOORD0;
					//float3 worldNormal:TEXCOORD1;

					//方法二,放在Object空间下计算
					float3 viewDir:TEXCOORD0;
					float3 normal:TEXCOORD1;
				};

				v2f vert(appdata_base v) {
					v2f o;
					o.vertex = UnityObjectToClipPos(v.vertex);
					// 方法一,得到世界点,再到片元中计算视野方向
					//o.worldNormal = UnityObjectToWorldNormal(v.normal);
					//o.worldPos = mul(unity_ObjectToWorld,v.vertex);

					// 方法二,把视野方向在模型中就计算出来
					//o.worldNormal = UnityObjectToWorldNormal(v.normal);
					o.viewDir = ObjSpaceViewDir(v.vertex);
					o.normal = v.normal;

					return o;
				}

				float4 frag(v2f i) :SV_Target{

					/// 通过视野方向和世界法线方向求得边沿(视野方向和世界法线方向 垂直为边缘)

					// 方法一,得到世界点,再到片元中计算视野方向
					//float3 worldNormal = normalize(i.worldNormal);
					//float3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));

					// 方法二,把视野方向在模型中就计算出来
					float3 worldNormal = normalize(i.normal);
					float3 viewDir = normalize(i.viewDir);

					// 边缘
					float rim = 1 - dot(worldNormal,viewDir);  // 1- 让边沿为 1
					return _XRayColor * pow(rim,1 / _XRayPower);
				}

				ENDCG
			}
	}

		FallBack "Diffuse"
}

2、

Shader "Unity/XRay"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _Diffuse("Color",Color) = (1,1,1,1)
        _XRayColor("XRayColor",Color) = (1,1,1,1)
        _XRayPower("XRayPower",float) = 0

    }
        SubShader
        {
            Tags {"Queue" = "Geometry+1000" "RenderType" = "Opaque" }
            LOD 100

            //Xray效果
            Pass
            {
                Name "Xray"
                //忽略阴影,半透明物体不需要阴影,可开启此功能
                Tags{ "ForceNoShadowCasting" = "true" }
            //开启混合
            Blend SrcAlpha One
            //不进行任何颜色信息写入
            ZWrite Off
            //大于深度缓冲池中的颜色深度的片元才进行处理 其他的全部舍弃
            ZTest Greater

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

            float4 _XRayColor;
            float _XRayPower;

            struct v2f
            {
                float4 vertex:SV_POSITION;
                float3 normal:TEXCOORD0;
                float3 viewDir:TEXCOORD1;

            };

            v2f vert(appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.normal = v.normal;
                o.viewDir = ObjSpaceViewDir(v.vertex);
                return o;
            };

            fixed4 frag(v2f i) :SV_TARGET
            {
                float3 NormalDir = normalize(i.normal);
                float3 ViewDir = normalize(i.viewDir);

                float rim = 1 - saturate(dot(NormalDir,ViewDir));
                float4 rimColor = _XRayColor * pow(rim,1 / _XRayPower);
                return rimColor;
            };
            ENDCG
        }

            //正常的漫反射渲染
            Pass
            {

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

                sampler2D _MainTex;
                float4 _MainTex_ST;
                float3 _Diffuse;
                struct v2f
                {
                    float4 vertex:SV_POSITION;
                    float2 uv:TEXCOORD0;
                    float3 worldPos:TEXCOORD1;
                    float3 worldNormal:TEXCOORD2;
                };

                v2f vert(appdata_base v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                    o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                    o.worldNormal = UnityObjectToWorldNormal(v.normal);
                    return o;
                };

                fixed4 frag(v2f i) :SV_TARGET
                {
                    float3 worldNormalDir = normalize(i.worldNormal);
                    float3 WorldLightDir = normalize(UnityWorldSpaceLightDir(i.worldNormal));

                    float3 texColor = tex2D(_MainTex,i.uv);

                    float3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * texColor.rgb;

                    float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * texColor.rgb * (dot(worldNormalDir,WorldLightDir) * 0.5 + 0.5);

                    float3 color = diffuse + ambient;
                    return fixed4(color,1);
                };
                ENDCG
           }

        }
            Fallback "Diffuse"
}

3、Highlight Plus - All in One Outline & Selection Effects

Highlight Plus - All in One Outline & Selection Effects | VFX Shaders | Unity Asset Store

文章来源:https://blog.csdn.net/yangzhen_010/article/details/135385543
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。