// *********************************************************************** // Author : Kimch // Created : 2018-7-1 // Description : 角色Shader // Last Modified By : Kimch // Last Modified On : 2019-7-1 // *********************************************************************** // // *********************************************************************** Shader "MY/Hair" { Properties { _MainColor("Main Color", Color) = (1,1,1,1) _MainTex("Diffuse (RGB) Alpha (A)", 2D) = "white" {} _MainTexScale("MainTex Scale", Range(0, 1)) = 1.0 _NormalTex("Normal Map", 2D) = "Black" {} _NormalScale("Normal Scale", Range(0, 1)) = 1.0 _AnisoDir("Specular Shift(G),Specular Mask (B)", 2D) = "white" {} _SpecDetalScale("Specular Detal Scale", Range(0, 1)) = 1.0 _ShiftScale("Shift Scale", Range(0, 3)) = 1.0 _LightDirScale("LightDir Scale", Range(-10, 10)) = 1.0 _LightDirScale2("LightDir Scale2", Range(-10, 10)) = 1.0 [Header(Shift)] _PrimarySpecularColor("Primary Specular", Color) = (1,1,1,1) _PrimarySpecularShift("Primary Specular Shift", Range(-4, 1)) = 0.0 _PrimarySpecularScale("Primary Specular Scale", Range(0, 5)) = 1.0 _PrimarySpecularMultiplier("Primary Specular Multiplier", Range(0, 1000)) = 100.0 _SecondarySpecularColor("Secondary Specular", Color) = (0.5,0.5,0.5,1) _SecondarySpecularShift("Secondary Specular Shift", Range(-4, 1)) = 0.7 _SecondarySpecularScale("Secondary Specular Scale", Range(0, 5)) = 1.0 _SecondarySpecularMultiplier("Secondary Specular Multiplier", Range(0, 1000)) = 100.0 [Header(Light)] //_Unlitness("Unlitness", Range(0.0, 1.0)) = 0.5 _UnlitnessScale("light Scale", Range(0.0, 1.0)) = 1.0 [HideInInspector][Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull Mode", Float) = 2 [HideInInspector] _ZOffset("__ZOffset", Float) = 0.0 [HideInInspector] _ZDepth("__ZDepth", Float) = 0.0 _DiffCubeIBL("Custom Diffuse Cube", Cube) = "black" {} _DiffCubeIBLScale("Diff Cube IBL Scale", Range(0.0,0.3)) = 0.2 [Toggle] _ALPHATEST("ALPHA TEST ON", Int) = 0 _Cutoff("Alpha cutoff", Range(0,1)) = 0.5 } SubShader { //在半透明之前渲染 Tags {"Queue" = "AlphaTest+100" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout"} //Pass //{ // ZWrite On //写入深度,被遮挡的像素在下个Pass将不能通过深度测试 // ColorMask 0 //不输出颜色 //} Pass { Tags { "LightMode" = "ForwardBase" } Offset[_ZOffset],[_ZDepth] ZWrite on Cull back //[_Cull] Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma shader_feature _ALPHATEST_ON #pragma target 3.0 #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" //#define _HORIZONTAL_TANGENT sampler2D _MainTex, _AnisoDir,_NormalTex; float4 _MainTex_ST, _AnisoDir_ST,_NormalTex_ST; half _NormalScale; half4 _MainColor, _PrimarySpecularColor, _SecondarySpecularColor; half _PrimarySpecularShift, _PrimarySpecularScale, _PrimarySpecularMultiplier; half _SecondarySpecularScale, _SecondarySpecularShift, _SecondarySpecularMultiplier; half _Unlitness,_UnlitnessScale, _SpecDetalScale, _MainTexScale, _ShiftScale; samplerCUBE _DiffCubeIBL; float _DiffCubeIBLScale; float _LightDirScale; float _LightDirScale2; half _Cutoff; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 uv : TEXCOORD0; float4 tSpace0 : TEXCOORD1; float4 tSpace1 : TEXCOORD2; float4 tSpace2 : TEXCOORD3; float4 vertex : SV_POSITION; }; //获取头发高光 fixed StrandSpecular(fixed3 T, fixed3 V, fixed3 L, fixed exponent) { fixed3 H = normalize(L + V); fixed dotTH = dot(T, H); fixed sinTH = sqrt(1 - dotTH * dotTH); fixed dirAtten = smoothstep(-1, 0, dotTH); return dirAtten * pow(sinTH, exponent); } //沿着法线方向调整Tangent方向 fixed3 ShiftTangent(fixed3 T, fixed3 N, fixed shift) { return normalize(T + shift * N); } v2f vert(appdata_full v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f,o); o.vertex = UnityObjectToClipPos(v.vertex); o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex); o.uv.zw = TRANSFORM_TEX(v.texcoord, _NormalTex); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 albedo = tex2D(_MainTex, i.uv); #ifdef _ALPHATEST_ON clip(albedo.a - _Cutoff); #endif half3 albedorgb = lerp(albedo.rgb, fixed3(1, 1, 1), _MainTexScale); half3 diffuseColor = albedorgb * _MainColor.rgb; //法线相关 fixed3 bump = UnpackScaleNormal(tex2D(_NormalTex, i.uv.zw),_NormalScale); fixed3 worldNormal = normalize(half3(dot(i.tSpace0.xyz, bump), dot(i.tSpace1.xyz, bump), dot(i.tSpace2.xyz, bump)));//normalize(half3(i.tSpace0.z, i.tSpace1.z, i.tSpace2.z));// float3 worldPos = float3(i.tSpace0.w, i.tSpace1.w, i.tSpace2.w); fixed3 worldTangent = normalize(half3(i.tSpace0.x, i.tSpace1.x, i.tSpace2.x)); fixed3 worldBinormal = normalize(half3(i.tSpace0.y, i.tSpace1.y, i.tSpace2.y)); fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos)); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(worldPos)); fixed3 worldLightDir2 = worldLightDir; worldLightDir.y *= _LightDirScale2; worldLightDir2.y *= _LightDirScale; float4 texcoord; texcoord.xy = TRANSFORM_TEX(i.uv, _AnisoDir); fixed3 spec = tex2D(_AnisoDir, texcoord.xy).rgb;//i.uv //计算切线方向的偏移度 half shiftTex = spec.g * _ShiftScale;// * 0.6 调节平滑程度 #ifdef _HORIZONTAL_TANGENT half3 t1 = ShiftTangent(worldTangent, worldNormal, _PrimarySpecularShift + shiftTex); half3 t2 = ShiftTangent(worldTangent, worldNormal, _SecondarySpecularShift + shiftTex); #else half3 t1 = ShiftTangent(worldBinormal, worldNormal, _PrimarySpecularShift + shiftTex); half3 t2 = ShiftTangent(worldBinormal, worldNormal, _SecondarySpecularShift + shiftTex); #endif //计算高光强度 half3 spec1 = StrandSpecular(t1, worldViewDir, worldLightDir, _PrimarySpecularMultiplier)* _PrimarySpecularColor + StrandSpecular(t1, worldViewDir, worldLightDir2, _PrimarySpecularMultiplier)* _PrimarySpecularColor; half3 spec2 = StrandSpecular(t2, worldViewDir, worldLightDir, _SecondarySpecularMultiplier)* _SecondarySpecularColor + StrandSpecular(t2, worldViewDir, worldLightDir2, _SecondarySpecularMultiplier)* _SecondarySpecularColor; fixed4 finalColor = fixed4(0, 0, 0, 1);// fixed4(diffuseColor.rgb, albedo.a);// finalColor.rgb += spec1 * _PrimarySpecularScale;//第一层高光 finalColor.rgb += spec2 * _SecondarySpecularScale; finalColor.rgb *= spec.r*_SpecDetalScale*spec.b;//高光细节 //受灯光影响 float NdotL = saturate(dot(worldNormal, worldLightDir)); half3 diff = saturate(lerp(0.25, 1, NdotL)); diff = diff * diffuseColor * _LightColor0.rgb * _UnlitnessScale; half3 ambient = fixed3(0.0, 0.0, 0.0); //UNITY_LIGHTMODEL_AMBIENT.xyz * 0.5; half3 diffIBL = texCUBE(_DiffCubeIBL, worldNormal);//不能使用blurredWorldNormal,因为blurredWorldNormal不连续平滑,会导致最终效果出现波纹!! ambient = diffIBL * _DiffCubeIBLScale * _LightColor0.rgb; fixed4 c; c.rgb = diffuseColor * 0.5 + diff + finalColor + ambient * 1.3; //c.rgb = diffuseColor + finalColor + ambient*1.3; #ifdef _ALPHATEST_ON c.a = albedo.a; #else c.a = 1; #endif return c; }; ENDCG } } FallBack "Mobile/VertexLit" }