e4s-game/gamedata/shaders/d3d11/screenspacecontactshadows.hlsl
2026-06-18 01:18:29 +03:00

66 lines
1.8 KiB
HLSL

#ifndef screenspacecontactshadows_hlsl_included
#define screenspacecontactshadows_hlsl_included
#ifndef HUD_SHADOWS_STEPS
#define HUD_SHADOWS_STEPS 35
#endif
#ifndef HUD_SHADOWS_TRACE_LEN
#define HUD_SHADOWS_TRACE_LEN 0.07f
#endif
float SampleHudHitPoint(float2 TexCoord)
{
float depth = s_position.SampleLevel(smp_nofilter, TexCoord, 0).x;
return depth_unpack.z * rcp(min(1.0f, depth * 50.0f) - depth_unpack.w);
}
float2 GetPointTexCoord(float3 Point)
{
Point.xy *= rcp(pos_decompression_params_hud.xy * Point.z);
return saturate(Point.xy * 0.5f + 0.5f);
}
void RayTraceContactShadow(float2 TexCoord, float3 Point, float3 LightDir, inout float3 Light)
{
Point.xyz *= 0.99f;
LightDir *= min(Point.z, HUD_SHADOWS_TRACE_LEN);
float4 StartProj = mul(m_P_hud, float4(Point, 1.0f)); StartProj.xyz /= StartProj.w;
float4 EndProj = mul(m_P_hud, float4(Point - LightDir, 1.0f)); EndProj.xyz /= EndProj.w;
StartProj.xy = StartProj.xy * float2(0.5f, -0.5f) + 0.5f; StartProj.z *= 0.02f;
EndProj.xy = EndProj.xy * float2(0.5f, -0.5f) + 0.5f; EndProj.z *= 0.02f;
LightDir = EndProj.xyz - StartProj.xyz;
StartProj.xy = TexCoord.xy;
float Len = GetMaxDirLength(StartProj.xyz, rcp(LightDir));
LightDir *= min(1.0f, Len);
LightDir *= rcp(HUD_SHADOWS_STEPS);
float ContactShadow = 0.0f;
[unroll(HUD_SHADOWS_STEPS)]
for (int i = 0; i < HUD_SHADOWS_STEPS; ++i)
{
StartProj.xyz += LightDir * float(0.8f + 0.4f * Hash(StartProj.xyz));
float HitDepth = s_position.SampleLevel(smp_nofilter, StartProj.xy, 0).x;
if (HitDepth <= StartProj.z)
{
ContactShadow += 0.2f;
if (ContactShadow >= 1.0f)
{
ContactShadow = 1.0f;
break;
}
}
}
ContactShadow *= GetBorderAtten(StartProj.xy, 0.0125f);
Light *= 1.0f - saturate(ContactShadow);
}
#endif