2025-09-23 15:36:38 +08:00

201 lines
8.1 KiB
GLSL

Shader "Unlit/MaoFaF"
{
Properties
{
_MainTex("MainTex",2D)="white"{}//毛皮颜色
_Noise ("Noise", 2D) = "white" {}//毛发形状贴图
_Noise2 ("Noise", 2D) = "white" {}//毛发形状扰动贴图
_Mask("Mask",2D)="white"{}
_Color("Color",color)=(1,1,1,1)//毛发的染色
_LayerOffset("LayerOffset",float)=0.1//当前层的偏移量
_FurLength("FurLength",float)=1//总体毛发长度
//_ShadowStrength("FurShadow",Range(0,1))=0.5//从根部到顶部阴影颜色过渡曲线
_ShadowColor("ShadowColor",color)=(1,1,1,1)//由根部到顶部阴影的颜色
_R("R",Range(0,1))=0.5
//_LengthMut("LengthMut",Range(0,5))=1
//[Enum(Off,0,On,1)]_ZWriteMode("ZWrite Mode", Int) = 1
//_FurOffset("FurOffset",vector)=(0,1,0,0)//毛发偏移方向
}
SubShader
{
Tags { "RenderType" = "Transparent" "IgnoreProjector" = "True" "Queue" = "Transparent" }
//LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
Cull Back
ZWrite On //[_ZWriteMode]
HLSLPROGRAM
#pragma multi_compile_instancing
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS //接受主光源阴影
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE //投射主光源的阴影
#pragma multi_compile _ _SHADOWS_SOFT //软阴影
#pragma multi_compile _ _ADDITIONAL_LIGHTS //附加光源
#pragma multi_compile _ INSTANCE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct appdata
{
float4 vertex : POSITION;
float3 normal:NORMAL;
float4 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 wpos:TEXCOORD1;
float3 wnormal:TEXCOORD2;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
TEXTURE2D( _MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D( _Mask);SAMPLER(sampler_Mask);
TEXTURE2D(_Noise);SAMPLER(sampler_Noise);
TEXTURE2D(_Noise2);SAMPLER(sampler_Noise2);
CBUFFER_START(UnityPerMaterial)
float4 _Color;
float4 _Noise_ST;
float _LayerOffset;
float _FurLength;
float3 _ShadowColor;
float _ShadowStrength;
float _R;
float _LengthMut;
float _LayerCount;
CBUFFER_END
//UNITY_INSTANCING_BUFFER_START(Props)
// UNITY_DEFINE_INSTANCED_PROP(float4,_Color)
//UNITY_INSTANCING_BUFFER_END(Props)
float rand(float3 seed, float Min, float Max)
{
float f = sin(dot(seed, float3(127.1, 337.1, 256.2)));
f = -1 + 2 * frac(f * 43785.5453123);
return lerp(Min, Max, f);
}
float RandomRange_float(float2 Seed, float Min, float Max)
{
float randomno = frac(sin(dot(Seed, float2(12.9898, 78.233)))*43758.5453);
return lerp(Min, Max, randomno);
}
float Remap(float x,float inMin,float inMax,float toMin ,float toMax)
{
return (x-inMin)/(inMax-inMin)*(toMax-toMin)+toMin;
}
v2f vert (appdata v ,uint instanceID : SV_InstanceID)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v,o);
#if defined(INSTANCE)
_LayerOffset=instanceID/_LayerCount;
#endif
//float d=sign(v.normal.z)
float3 dir=normalize(v.normal+float3(0,-0.8,-abs(v.normal.y)*0.4));
v.vertex.xyz=v.vertex.xyz+dir*(_LayerOffset*_LayerOffset*0.8)*_FurLength*1;
//v.vertex.xyz+=mul(unity_WorldToObject,_FurOffset);//不需要位移
o.vertex = TransformObjectToHClip(v.vertex);
o.wpos=mul(UNITY_MATRIX_M,v.vertex);
o.uv = v.uv;
o.wnormal=TransformObjectToWorldNormal(v.normal);//(mul(v.normal,(float3x3)unity_WorldToObject));
return o;
}
// [earlydepthstencil]
float4 frag (v2f i ,uint instanceID : SV_InstanceID) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i)
#if defined(INSTANCE)
_LayerOffset=instanceID/_LayerCount;
#endif
//UNITY_ACCESS_INSTANCED_PROP(Props,_Color);
float3 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex,i.uv).rgb ;
//return float4(albedo*0.1,1);
float3 color = albedo*1*_Color.rgb;
//从底部到顶部阴影过渡
float mask = SAMPLE_TEXTURE2D(_Mask, sampler_Mask,i.uv).r;
color =lerp(_ShadowColor,color,saturate(pow( _LayerOffset,2)+_ShadowStrength-mask*0.2+0.5));
mask=Remap(mask,0,1,0.8,1);
//修改毛发的密度与重复度
float3 noise2 = SAMPLE_TEXTURE2D(_Noise2, sampler_Noise2,i.uv*10+i.uv*(1-mask)*5);
float3 noise = SAMPLE_TEXTURE2D(_Noise,sampler_Noise, i.uv*10+noise2*50+i.uv*(1-mask)*50);
noise=lerp(noise2,noise,0.6);
float alpha = (saturate(noise*1.8) - (_LayerOffset )-(1-mask));
float3 N=normalize(i.wnormal);
float3 V=normalize(_WorldSpaceCameraPos-i.wpos);
float3 L=normalize(_MainLightPosition.xyz);
float3 H=normalize(V+L);
float NdL=max(dot(N,L),0.00001);
float NdV=dot(N,V);
float VdH=(dot(V,H));
float3 r=normalize(reflect(-L,N));
float RdV=(dot(r,V));
//绒毛材质
float _R=0.6;
float3 f0=0.15;
float3 f=F_Schlick(f0,VdH);
float3 c1=D_Charlie(RdV,_R)*V_Charlie(NdL,NdV,_R)*PI*f*_MainLightColor*NdL;
float3 c2=D_Charlie(NdV,1)*_MainLightColor*0.1;
float3 diff=NdL*FabricLambert(_R)*color*_MainLightColor*PI*(1-f);
int addCount=GetAdditionalLightsCount();
float3 addColor=0;
for (int k=0;k<addCount;k++)
{
Light addLight= GetAdditionalLight(0,i.wpos);
float addNdl=max(dot(N,addLight.direction),0.0001);
float3 c1=D_Charlie(RdV,_R)*V_Charlie(addNdl,NdV,_R)*PI*f*addLight.color*addNdl*addLight.distanceAttenuation;
float3 c2=D_Charlie(NdV,1)*addLight.color*0.1;
addColor+=addNdl*FabricLambert(_R)*color*_MainLightColor*PI*(1-f)+c1+c2;
}
//物理的环境高光和环境漫反射
float aa=1;
BRDFData brdfData;
InitializeBRDFData(color+addColor*0.6,0,1,0.2,aa, brdfData);
half3 ambient_contrib = SampleSH(float4(N, 1));
float3 ambient = 0.3 * (color+addColor*0.6);// 随便乘个暗的系数
float3 iblDiffuse = max(half3(0, 0, 0), ambient.rgb + ambient_contrib);
float3 inssp= GlobalIllumination(brdfData,iblDiffuse,1,i.wpos,N,V);
return float4(saturate(c2+c1+diff+inssp)+addColor*0.2,saturate(alpha));
}
ENDHLSL
}
}
}