// Add this property somewhere (material or CBUFFER as fits your setup)
float _ShadowBlurRadius; // e.g. 0.75–2.0
void MainLight_float(float3 WorldPos, out float3 Direction, out float3 Color, out float DistanceAtten, out float ShadowAtten)
Direction = float3(0.5, 0.5, 0);
// Build the coord used for shadow sampling
float4 clipPos = TransformWorldToHClip(WorldPos);
float4 shadowCoord = ComputeScreenPos(clipPos);
float4 shadowCoord = TransformWorldToShadowCoord(WorldPos);
Light mainLight = GetMainLight(shadowCoord);
Direction = mainLight.direction;
DistanceAtten = mainLight.distanceAttenuation;
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
float4 shadowParams = GetMainLightShadowParams();
// Use a small cross/corner kernel; tweak _ShadowBlurRadius for strength.
// Screen-space resolve path: sample the screen-space shadow texture directly
// Convert to normalized screen UV
float2 uv = shadowCoord.xy / shadowCoord.w;
// _ScreenParams.zw == (1/width, 1/height)
float2 texel = _ScreenParams.zw * _ShadowBlurRadius;
// A simple 4-corner kernel
float2 k0 = float2(-0.5, -0.5) * texel;
float2 k1 = float2( 0.5, -0.5) * texel;
float2 k2 = float2(-0.5, 0.5) * texel;
float2 k3 = float2( 0.5, 0.5) * texel;
// The screen-space shadow texture encodes attenuation (1 = lit, 0 = fully shadowed)
// Names are from URP; adjust if your shader has different sampler names.
float s0 = SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_ScreenSpaceShadowmapTexture, uv + k0).r;
float s1 = SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_ScreenSpaceShadowmapTexture, uv + k1).r;
float s2 = SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_ScreenSpaceShadowmapTexture, uv + k2).r;
float s3 = SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_ScreenSpaceShadowmapTexture, uv + k3).r;
ShadowAtten = (s0 + s1 + s2 + s3) * 0.25;
// Shadowmap path: jitter the shadowmap UV used by SampleShadowmap
// In URP, shadowSamplingData.shadowmapSize is typically (W, H, 1/W, 1/H)
// We’ll use .zw as texel size.
float2 texel = shadowSamplingData.shadowmapSize.zw * _ShadowBlurRadius;
float2 k0 = float2(-0.5, -0.5) * texel;
float2 k1 = float2( 0.5, -0.5) * texel;
float2 k2 = float2(-0.5, 0.5) * texel;
float2 k3 = float2( 0.5, 0.5) * texel;
atten += SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture),
sc, shadowSamplingData, shadowParams, false);
atten += SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture),
sc, shadowSamplingData, shadowParams, false);
atten += SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture),
sc, shadowSamplingData, shadowParams, false);
atten += SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture),
sc, shadowSamplingData, shadowParams, false);
ShadowAtten = atten * 0.25;
// If you want to blend with the engine's shadow strength:
// float strength = GetMainLightShadowStrength();
// ShadowAtten = lerp(1.0, ShadowAtten, strength);