37 lines
1.5 KiB
HLSL
Raw Normal View History

2025-07-22 15:39:27 +08:00
#ifndef FAKE_SHADOWS_INCLUDED
#define FAKE_SHADOWS_INCLUDED
half4 _FakeShadowsLights[4];
const half epsilon = 0.0001;
// half4 player(pos.xyz, radius)
half CalcFakeShadowPerLight(half4 light, half3 playerPos, half playerRad, half3 posToPlayer, half3 posWS)
{
// Calc dot
half3 playerToLight = normalize(light.xyz - playerPos);
half d = dot(posToPlayer, playerToLight);
float r = 1 - playerRad;
d = saturate((d - r) / (1 - r)); // remap range: r~1 -> 0~1
// Attenuation
half distLightToPos = distance(posWS, light.xyz);
half atten = 1 - saturate(distLightToPos / (light.w + epsilon)); // Apply light radius
atten = atten * atten; // Inverse Square Law
// Adjust attenuation and reverse
return 1 - saturate(d * atten);
}
// shadowArgs: (x)radius, (y)strength
void FakeShadows_float(in half3 playerPosition, in half4 shadowArgs, in half3 positionWS, out half shadows)
{
half3 posToPlayer = normalize(playerPosition - positionWS);
shadows = CalcFakeShadowPerLight(_FakeShadowsLights[0], playerPosition, shadowArgs[0], posToPlayer, positionWS);
shadows *= CalcFakeShadowPerLight(_FakeShadowsLights[1], playerPosition, shadowArgs[0], posToPlayer, positionWS);
shadows *= CalcFakeShadowPerLight(_FakeShadowsLights[2], playerPosition, shadowArgs[0], posToPlayer, positionWS);
shadows *= CalcFakeShadowPerLight(_FakeShadowsLights[3], playerPosition, shadowArgs[0], posToPlayer, positionWS);
shadows = shadows * shadows * shadows; // enhance shadows
shadows = saturate(shadows + (1 - shadowArgs[1]));
}
#endif