2025-05-18 01:04:31 +08:00

218 lines
7.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ***********************************************************************
// 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"
}