Bootstrap

UnityShader——流光效果

声明:本文为个人笔记,用于学习研究使用非商用,内容为个人研究及综合整理所得,若有违规,请联系,违规必改。


UnityShader学习目录



前言

Unity2019.3.6
AmplifyShaderEditor


一、实现原理

Time控制UV的变化,再采样一张流光贴图.即可实现流光效果.下列包含两个流光效果及源码作为学习参考.

二、效果及源码展示

1.流光效果

效果描述:
1.边缘光(菲尼尔),
2.从上到下扫描光.
效果图如下:
效果图

AmplifyShaderEditor节点图如下:
在这里插入图片描述
参数设置如下:
在这里插入图片描述
代码如下:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

Shader "Unlit/Scan_Code01"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_RimMin("RimMin",Range(-1,1)) = 0.0
		_RimMax("RimMax",Range(0,2)) = 1.0
		_InnerColor("Inner Color",Color) = (0.0,0.0,0.0,0.0)
		_RimColor("Rim Color",Color) = (1,1,1,1)
		_RimIntensity("Rim Intensity",Float) = 1.0
		_FlowTilling("Flow Tilling",Vector) = (1,1,0,0)
		_FlowSpeed("Flow Speed",Vector) = (1,1,0,0)
		_FlowTex("Flow Tex",2D) = "white"{}
		_FlowIntensity("Flow Intensity",Float) = 0.5
		_InnerAlpha("Inner Alpha",Range(0.0,1.0)) = 0.0
	}
	SubShader
	{
		Tags { "Queue"="Transparent" }
		LOD 100

		Pass
		{
			ZWrite Off
			Blend SrcAlpha One
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
				float3 normal : NORMAL;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 pos_world : TEXCOORD1;
				float3 normal_world : TEXCOORD2;
				float3 pivot_world : TEXCOORD3;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float _RimMin;
			float _RimMax;
			float4 _InnerColor;
			float4 _RimColor;
			float _RimIntensity;
			float4 _FlowTilling;
			float4 _FlowSpeed;
			sampler2D _FlowTex;
			float _FlowIntensity;
			float _InnerAlpha;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				float3 normal_world = mul(float4(v.normal, 0.0), unity_WorldToObject).xyz;
				float3 pos_world = mul(unity_ObjectToWorld, v.vertex).xyz;
				o.normal_world = normalize(normal_world);
				o.pos_world = pos_world;
				o.pivot_world = mul(unity_ObjectToWorld, float4(0.0, 0.0, 0.0, 1.0)).xyz;
				o.uv = v.texcoord;
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				half3 normal_world = normalize(i.normal_world);
				half3 view_world = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);
				
				//
				half NdotV = saturate(dot(normal_world, view_world));
				half fresnel = 1.0 - NdotV;
				fresnel = smoothstep(_RimMin, _RimMax, fresnel);
				half emiss = tex2D(_MainTex, i.uv).r;
				emiss = pow(emiss, 5.0);

				half final_fresnel = saturate(fresnel + emiss);

				half3 final_rim_color = lerp(_InnerColor.xyz, _RimColor.xyz * _RimIntensity, final_fresnel);
				half final_rim_alpha = final_fresnel;
				//流光
				half2 uv_flow = (i.pos_world.xy - i.pivot_world.xy) * _FlowTilling.xy;
				uv_flow = uv_flow + _Time.y * _FlowSpeed.xy;
				float4 flow_rgba = tex2D(_FlowTex, uv_flow) * _FlowIntensity;

				float3 final_col = final_rim_color + flow_rgba.xyz;
				float final_alpha = saturate(final_rim_alpha + flow_rgba.a + _InnerAlpha);
				return float4(final_col, final_alpha);
			}
			ENDCG
		}
	}
}

(i.pos_world.xy - i.pivot_world.xy)
用于计算UV位置,达到从上到下的扫描效果.

2.流光效果二

效果描述:
1.中间遮罩剔除
2.扭曲
3.颜色叠加

效果图如下:
流光效果二
代码如下:

Shader "Unlit/Scan_Code02"
{
    Properties
    {
        [Header(RenderingMode)]
        [Enum(UnityEngine.Rendering.BlendMode)]_SrcBlend("SrcBlend" ,int   )=0
        [Enum(UnityEngine.Rendering.BlendMode)]_DstBlend("DstBlend",int)=0
        [Enum(UnityEngine.Rendering.CullMode)]_Cull("Cull",int)=0

        [Header(Base)]
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Color",color)=(1,1,1,1)
        _Instensity("Instensity",float)=0.5
        _MainUVSpeedX("MainUVSpeed X",float)=1
        _MainUVSpeedY("MainUVSpeed Y",float)=1

        [Header(Mask)]
        [Toggle]_MASKENABLED("Mask Enable",int)=0
         _MaskTex("MaskTex",2D)="white"{}
        _MaskUVSpeedX("MaskUVSpeed X",float)=0
        _MaskUVSpeedY("MaskUVSpeed Y",float)=0

        [Header(Distort)]
        [MaterialToggle(DISTORTENABLED)]_DISTORTENABLED_ON("Distort Enable",int)=0
        _DistortTex("DistortTex",2d)="white"{}
        _Distort("Distort",Range(0,1))=0
        _DistortUVSpeedX("DistortUVSpeed X",float)=0
        _DistortUVSpeedY("DistortUVSpeed Y",float)=0
    }
    SubShader
    {
        Blend [_SrcBlend][_DstBlend]
        Tags { "Queue"="Transparent" }       
        Cull [_Cull]
        Pass
        {            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag           
            #pragma shader_feature _ _MASKENABLED_ON
            #pragma shader_feature _ DISTORTENABLED
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 uv : TEXCOORD0;            
                float4 vertex : SV_POSITION;
                float2 uv2:TEXCOORD1;
            };  

            fixed4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            half _Instensity;
            float _MainUVSpeedX,_MainUVSpeedY;
            sampler2D _MaskTex;
            float4 _MaskTex_ST;//Mask贴图的UV元素
            float _MaskUVSpeedX,_MaskUVSpeedY;//控制MaskUV的变量
            sampler2D _DistortTex;
            float4 _DistortTex_ST;
            float _Distort;
            float _DistortUVSpeedX,_DistortUVSpeedY;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv.xy=v.uv*_MainTex_ST.xy+_MainTex_ST.zw+float2(_MainUVSpeedX,_MainUVSpeedY)*_Time.y;//主贴图UV流动
                // o.uv = TRANSFORM_TEX(v.uv, _MainTex)+float2(_MainUVSpeedX,_MainUVSpeedY)*_Time.y;            
                #if _MASKENABLED_ON
                    o.uv.zw=TRANSFORM_TEX(v.uv,_MaskTex)+float2(_MaskUVSpeedX,_MaskUVSpeedY)*_Time.y;//Mask贴图UV流动
                #endif

                #if DISTORTENABLED
                o.uv2=TRANSFORM_TEX(v.uv,_DistortTex)+float2(_DistortUVSpeedX,_DistortUVSpeedY)*_Time.y;
                #endif
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 distort=i.uv.xy;
                
                #if DISTORTENABLED
                    fixed4 distortTex=tex2D(_DistortTex,i.uv2);
                    distort=lerp(i.uv.xy,distortTex,_Distort);
                #endif

                fixed4 c = tex2D(_MainTex, distort);  
                c*=_Color*_Instensity;     

                #if  _MASKENABLED_ON
                    fixed4 maskTex=tex2D(_MaskTex,i.uv.zw); 
                    c*=maskTex;               
                #endif  
                return c;
            }
            ENDCG
        }
    }
}

参数设置如下:
参数设置

总结

保持饥饿,保持愚蠢.

这世界唯一能够相信的就是你付出的努力和你走过的路.

;