218 lines
7.9 KiB
Plaintext
218 lines
7.9 KiB
Plaintext
// ***********************************************************************
|
||
// 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"
|
||
} |