You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.8 KiB
Plaintext

3 years ago
static const half MAX_TRANSLUNCENCY = 5;
static const half MAX_REFLECTION = 22;
#define PIc 3.1415926
#define SQRT2PI 2.50663
half3 BackLighting(half3 lightDirection, half3 viewDir, half3 worldNormal, half attenuation,
half distortion, half power, half scale, half4 subsurfaceColor)
{
half3 H = normalize(lightDirection + worldNormal * distortion);
half I = pow(saturate(dot(viewDir, -H)), power) * scale;
return subsurfaceColor * 5 * I * attenuation;
}
inline half square(half x)
{
return x * x;
}
inline half Hair_G(half B, half Theta)
{
return exp(-0.5 * square(Theta) / (B * B)) / (SQRT2PI * B);
}
half HairIOF(half Eccentric)
{
half n = 1.55;
half a = 1 - Eccentric;
half ior1 = 2 * (n - 1) * (a * a) - n + 2;
half ior2 = 2 * (n - 1) / (a * a) - n + 2;
return 0.5f * ((ior1 + ior2) + 0.5f * (ior1 - ior2));
}
inline half3 SpecularFresnel(half3 F0, half vDotH)
{
return F0 + (1.0f - F0) * pow(1 - vDotH, 5);
}
half3 DiffuseLight(half3 Albedo, half3 L, half3 N)
{
half DiffuseScatter = (1.0 / PIc) * saturate(dot(N, L));
return Albedo * DiffuseScatter;
}
const half Alpha[] =
{
-0.0998,
0.0499f,
0.1996
};
half3 HairSpecularMarschner(half3 Albedo, half3 L, half3 V, half3 N, half Area, half smoothness)
{
half3 S = 0;
const half VoL = dot(V, L);
const half SinThetaL = dot(N, L);
const half SinThetaV = dot(N, V);
half cosThetaL = sqrt(max(0, 1 - SinThetaL * SinThetaL));
half cosThetaV = sqrt(max(0, 1 - SinThetaV * SinThetaV));
half CosThetaD = sqrt((1 + cosThetaL * cosThetaV + SinThetaV * SinThetaL) / 2.0);
const half3 Lp = L - SinThetaL * N;
const half3 Vp = V - SinThetaV * N;
const half CosPhi = dot(Lp, Vp) * rsqrt(dot(Lp, Lp) * dot(Vp, Vp) + 1e-4);
const half CosHalfPhi = sqrt(saturate(0.5 + 0.5 * CosPhi));
half B[] =
{
Area + square(1 - smoothness),
Area + square(1 - smoothness) / 2,
Area + square(1 - smoothness * 2)
};
half hairIOF = HairIOF(0);
half F0 = square((1 - hairIOF) / (1 + hairIOF));
half3 Tp;
half Mp, Np, Fp, f;
half ThetaH = SinThetaL + SinThetaV;
// R
Mp = Hair_G(B[0], ThetaH - Alpha[0]);
Np = 0.25 * CosHalfPhi;
Fp = SpecularFresnel(F0, sqrt(saturate(0.5 + 0.5 * VoL)));
S += (Mp * Np) * (Fp * lerp(1, 0, saturate(-VoL)));
// TRT
Mp = Hair_G(B[2], ThetaH - Alpha[2]);
f = SpecularFresnel(F0, CosThetaD * 0.5f);
Fp = square(1 - f) * f;
Tp = pow(Albedo, 0.8 / CosThetaD);
Np = exp(17 * CosPhi - 16.78);
S += (Mp * Np) * (Fp * Tp);
return S;
}
half3 HairBxDF(half3 Albedo, half3 N, half3 V, half3 L, half Shadow, half reflectionArea, half smoothness)
{
return DiffuseLight(Albedo, L, N) + HairSpecularMarschner(Albedo, L, V, N, reflectionArea, clamp(smoothness, 0, 0.99)) * Shadow;
}
void URPLighting_float(half3 worldNormal, half3 viewDirection, half3 lightDirection, half attenuation,
half4 SpecularColor, half specularIntensity, half reflectionArea, half smoothness,
out half4 Color)
{
#ifdef SHADERGRAPH_PREVIEW
Color = 1;
#else
half3 marshnerLighting = SpecularColor * MAX_REFLECTION * specularIntensity *
HairBxDF(
half3(0, 0, 0),
worldNormal,
viewDirection,
-lightDirection,
attenuation,
reflectionArea,
smoothness
);
Color = half4(marshnerLighting.x, marshnerLighting.y, marshnerLighting.z, 1);
#endif
}
void URPBackLighting_float(half3 lightDirection, half3 viewDir, half3 worldNormal, half attenuation,
half distortion, half power, half scale, half4 subsurfaceColor, out half4 Color)
{
Color = 1;
Color.xyz = BackLighting(lightDirection, viewDir, worldNormal, attenuation, distortion, power, scale, subsurfaceColor);
}