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