Files
com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsMaterialEvaluation.hlsl

194 lines
8.0 KiB
HLSL

#ifndef UTS_MATERIAL_EVALUATION
#define UTS_MATERIAL_EVALUATION
#define ColorSpaceDielectricSpec half4(0.22, 0.22, 0.22, 0.779)
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Lighting/UtsShadowEvaluation.hlsl"
struct UtsShadeMask
{
float baseShadeMask;
float firstShadeMask;
};
float RoughnessToBlinnPhongSpecularExponent(float roughness)
{
return clamp(2 * rcp(roughness * roughness) - 2, FLT_EPS, rcp(FLT_EPS));
}
float StepFeatherToon(float value,float step,float feather)
{
return saturate((value - step + feather) / feather);
}
float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, float3 V, float3 L)
{
#ifdef _PBR_MODE_OFF
return 0;
#else
float3 specTerm;
float3 N = bsdfData.normalWS;
float3 H = normalize(L + V);
float NdotL = dot(N, L);
float NdotH = saturate(dot(N, H));
float clampedNdotV = ClampNdotV(preLightData.NdotV);
float clampedNdotL = saturate(NdotL);
float partLambdaV;
float3 DV = 0;
#ifdef _PBR_MODE_STANDARD
partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGX(NdotH, abs(NdotL), clampedNdotV, bsdfData.roughnessT, partLambdaV);
#elif _PBR_MODE_ANISOTROPY
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
ConvertAnisotropyToRoughness(bsdfData.perceptualRoughness, bsdfData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For anisotropy we must not saturate these values
float TdotH = dot(bsdfData.tangentWS, H);
float TdotL = dot(bsdfData.tangentWS, L);
float BdotH = dot(bsdfData.bitangentWS, H);
float BdotL = dot(bsdfData.bitangentWS, L);
// We use abs(NdotL) to handle the none case of double sided
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.coatRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
float normalizeSpec = DV * rcp(specularExponent + 2) * 2 * PI;
//DV *= StepFeatherToon(normalizeSpec,specularStep,specularFeather);
DV = DV * normalizeSpec * _KKColor.rgb;
#elif _PBR_MODE_TOON
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = pow(NdotH, 5.0 * specularExponent);
DV = StepFeatherToon(DV, _ToonSpecularStep, _ToonSpecularFeather);
//specTerm = pow(NdotH, 5.0 * specularExponent);
//specTerm = StepFeatherToon(specTerm, _ToonSpecularStep, _ToonSpecularFeather);
//return specTerm * ColorSpaceDielectricSpec.rgb * clampedNdotL;
#endif
specTerm = DV * preLightData.specularFGD;
specTerm = specTerm * clampedNdotL;
return specTerm;
#endif
}
half3 FitWithCurveApprox(half NdotL, half Curvature)
{
half curva = (1.0 / mad(Curvature, 0.5 - 0.0625, 0.0625) - 2.0) / (16.0 - 2.0);
half oneMinusCurva = 1.0 - curva;
half3 curve0;
{
half3 rangeMin = half3(0.0, 0.3, 0.3);
half3 rangeMax = half3(1.0, 0.7, 0.7);
half3 offset = half3(0.0, 0.06, 0.06);
half3 t = saturate(mad(NdotL, 1.0 / (rangeMax - rangeMin), (offset + rangeMin) / (rangeMin - rangeMax)));
half3 lowerLine = (t * t) * half3(0.65, 0.5, 0.9);
lowerLine.r += 0.045;
lowerLine.b *= t.b;
half3 m = half3(1.75, 2.0, 1.97);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 0.99) - m);
upperLine = saturate(upperLine);
half3 lerpMin = half3(0.0, 0.35, 0.35);
half3 lerpMax = half3(1.0, 0.7, 0.6);
half3 lerpT = saturate(mad(NdotL, 1.0 / (lerpMax - lerpMin), lerpMin / (lerpMin - lerpMax)));
curve0 = lerp(lowerLine, upperLine, lerpT * lerpT);
}
half3 curve1;
{
half3 m = half3(1.95, 2.0, 2.0);
half3 upperLine = mad(NdotL, m, half3(0.99, 0.99, 1.0) - m);
curve1 = saturate(upperLine);
}
float oneMinusCurva2 = oneMinusCurva * oneMinusCurva;
return lerp(curve0, curve1, mad(oneMinusCurva2, -1.0 * oneMinusCurva2, 1.0));
}
DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData, SHADOW_TYPE shadow,
float3 lightColor, float3 V, float3 L, float2 uv,
float diffuseDimmer, float specularDimmer)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
{
shadow = smoothstep(0.4, 0.6, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
shadow *= GetHairShadow(posInput, L);
#endif
#if _SHADING_MODE_SDF
float angle;
float3 sdfTexture = SampleSDFTexture(L, uv, angle); // r: sdf shadow, g: sdf highlight, b: fixed shadow
float shadowSmoothLevel = _SDFShadowSmoothLevel / 10.0;
float sdfShadowMask = smoothstep(angle - shadowSmoothLevel, angle + shadowSmoothLevel, sdfTexture.r);
float sdfHighlight = sdfTexture.g * _SDFHighlightStrength;
#endif
float3 diffuseTerm = 0.0;
float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L);
#if _USE_SHADING_RAMP_MAP_ON
#if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5;
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * shadow.x, 0.0), _ShadingIndex, 0.0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor;
specularTerm *= saturate(NdotL) * shadow;
#elif _SHADING_MODE_SDF
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(sdfShadowMask * shadow.x, 0.0), _ShadingIndex, 0.0).rgb;
diffuseTerm = bsdfData.diffuseColor * rampColor;
specularTerm = (specularTerm + sdfHighlight) * sdfShadowMask * shadow;
#endif
#else
#if _SHADING_MODE_STANDARD
float NdotL = dot(bsdfData.normalWS, L);
float halfLambert = 0.5 * NdotL + 0.5;
float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
float baseShadeMask = saturate((halfLambert - (_1stShadeColorStep - firstColorFeatherForMask)) / (_1stShadeColorStep - (_1stShadeColorStep - firstColorFeatherForMask)));
baseShadeMask *= shadow.x;
float secondColorFeatherForMask = lerp(_2ndShadeColorFeather, 0.0, max(_SecondShadeOverridden, _ComposerMaskMode));
float firstShadeMask = saturate((halfLambert - (_2ndShadeColorStep - secondColorFeatherForMask)) / (_2ndShadeColorStep - (_2ndShadeColorStep - secondColorFeatherForMask)));
diffuseTerm = lerp(lerp(bsdfData.secondShadingDiffuseColor, bsdfData.firstShadingDiffuseColor, firstShadeMask), bsdfData.diffuseColor, baseShadeMask);
specularTerm *= baseShadeMask;
#elif _SHADING_MODE_SDF
float shadeMask = sdfShadowMask * sdfTexture.b * shadow.x;
diffuseTerm = lerp(bsdfData.firstShadingDiffuseColor, bsdfData.diffuseColor, shadeMask);
specularTerm = (specularTerm + sdfHighlight) * shadeMask;
#endif
#endif
lighting.diffuse += diffuseTerm * lightColor * diffuseDimmer;
lighting.specular += specularTerm * lightColor * specularDimmer;
#if _LIGHT_BASE_RIM_LIGHT_ON
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_RIM_LIGHT))
{
DirectLighting rimLightLighting = UtsEvaluateLighting_RimLight(posInput, bsdfData, preLightData, L, lightColor);
lighting.diffuse += rimLightLighting.diffuse;
lighting.specular += rimLightLighting.specular;
}
#endif
}
return lighting;
}
#endif