Shader "Zhanyou/Character/RideFlow" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} // ChannelTex,r表示流光亮度 [NoScaleOffset]_ChannelTex("Channel(R is the strength of flow)", 2D) = "white" {} _Emission ("Emission", Range(0, 1)) = 0.2 // 角色材质颜色,乘法运算 _Color("Blend Color", Color) = (1, 1, 1, 1) // Emission叠加颜色,加法运算 _AddColor("Additive Color", Color) = (0, 0, 0, 1) _Outline ("Outline Power", float) = 22 _OutlineColor ("Outline Color", Color) = (0.03, 0.03, 0.03, 1) _Cutoff("Alpha Cutoff", Range(0, 1)) = 0.5 // 流光贴图 _FlowTex ("Flow (RGB)", 2D) = "black" {} // 流光颜色 _FlowColor ("Flow Color", Color) = (1, 1, 1, 1) // 流光速度 _FlowSpeed ("Flow Speed", float) = 1 } SubShader { Tags { "Queue"="AlphaTest+10" "RenderType"="CharacterCutout" } Pass { Stencil { Ref 1 Comp always Pass replace } CGPROGRAM #include "UnityCG.cginc" #include "Gles2Helper.cginc" #pragma vertex vert #pragma fragment frag #pragma shader_feature UseFlowColor #pragma multi_compile_fog struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; float2 texcoord2 : TEXCOORD1; }; struct v2f { float4 pos : SV_POSITION; float2 texcoord : TEXCOORD0; float4 flowUv : TEXCOORD1; half rim : TEXCOORD2; UNITY_FOG_COORDS(3) }; uniform sampler2D _MainTex; uniform float4 _MainTex_ST; uniform half _Emission; uniform half4 _Color; uniform half4 _AddColor; uniform half _Outline; uniform half4 _OutlineColor; uniform sampler2D _ChannelTex; uniform sampler2D _FlowTex; uniform half4 _FlowTex_ST; uniform half4 _FlowColor; uniform float _FlowSpeed; v2f vert (appdata v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); o.pos = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); half3 objectViewDir = ObjSpaceViewDir(v.vertex); TANGENT_SPACE_ROTATION; o.rim = saturate(1 - normalize(MUL_3x3_WITH_VECTOR(rotation, objectViewDir)).z); o.rim = pow(o.rim, _Outline); o.texcoord = v.texcoord; o.flowUv.xy = v.texcoord2; o.flowUv.zw = TRANSFORM_TEX(v.texcoord2, _FlowTex); o.flowUv.w += _Time.y * _FlowSpeed; UNITY_TRANSFER_FOG(o, o.pos); return o; } uniform half _Cutoff; fixed4 frag(v2f i) : SV_TARGET { fixed4 col; col = tex2D(_MainTex, i.texcoord); clip(col.a - _Cutoff); col.rgb *= _Color.rgb; col.rgb += col.rgb * _Emission + _AddColor; col.rgb += _OutlineColor.rgb * _OutlineColor.a * i.rim; half4 channelCol = tex2D(_ChannelTex, i.flowUv.xy); fixed4 flowCol = tex2D(_FlowTex, i.flowUv.zw); flowCol *= _FlowColor; col.rgb += flowCol.rgb * flowCol.a * channelCol.r; UNITY_OPAQUE_ALPHA(col.a); UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } // 其实没有用的投影通道,但是Unity貌似会用这个通道做屏幕深度运算,所以保留一个 // Shadow Caster // ---- shadow caster pass: Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_shadowcaster #pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2 #include "HLSLSupport.cginc" #include "UnityShaderVariables.cginc" #define UNITY_PASS_SHADOWCASTER #include "UnityCG.cginc" #include "Lighting.cginc" half _Cutoff; sampler2D _MainTex; float4 _MainTex_ST; struct v2f { V2F_SHADOW_CASTER; float2 uv : TEXCOORD1; // _MainTex float3 worldPos : TEXCOORD2; }; v2f vert (appdata_full v) { v2f o; UNITY_TRANSFER_INSTANCE_ID(v,o); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = worldPos; TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) return o; } fixed4 frag (v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv); clip (c.a - _Cutoff); SHADOW_CASTER_FRAGMENT(i) } ENDCG } } CustomEditor "FlowToggleShaderGui" Fallback "Zhanyou/Character/NPC" }