66 lines
1.8 KiB
HLSL
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
|
|
|