218 lines
7.9 KiB
Plaintext
Raw Normal View History

2025-05-18 01:04:31 +08:00
// ***********************************************************************
// Author : Kimch
// Created : 2018-7-1
// Description : 角色Shader
// Last Modified By : Kimch
// Last Modified On : 2019-7-1
// ***********************************************************************
// <copyright file= "MY_PBS_Hair" company="kk"></copyright>
// ***********************************************************************
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"
}