Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to get directional light shadowmap in post process effect shader

Discussion in 'Universal Render Pipeline' started by piter00999, Nov 18, 2019.

  1. piter00999

    piter00999

    Joined:
    Jan 5, 2018
    Posts:
    19
    Hey there!
    I recently was trying to implement sun scattering for Unity, at first I tried to implement it for default render pipeline after I succeded I tried to rewrite this effect for URP however I can't find any way to get access to the directional light shadow map. Maybe someone already faced this problem and have a solution? In default rendering pipeline it was quite straightforward just attach command buffer to directional light and copy its shadow map texture to another one but this is not working anymore on URP.
     
  2. Bodkin

    Bodkin

    Joined:
    Jul 12, 2012
    Posts:
    11
  3. piter00999

    piter00999

    Joined:
    Jan 5, 2018
    Posts:
    19
    Unfortunately no, I ditched this project because of this.
     
  4. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    2,141
    In a post-processing effect or any screen-space pass, you can resolve the directional light's shadow map, based on the camera's depth texture. This is similar to how shadows are sampled in all the regular shaders. The difference being that the world position has to be reconstructed from depth first.

    Code (CSharp):
    1. //Note: ZW components is normalized screen position
    2. float ResolveShadowMask(float4 uv)
    3. {
    4.     float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv.xy).r;
    5.  
    6.     #if !UNITY_REVERSED_Z
    7.     deviceDepth = deviceDepth * 2.0 - 1.0;
    8.     #endif
    9.  
    10.     float3 vpos = ComputeViewSpacePosition(uv.zw, deviceDepth, unity_CameraInvProjection);
    11.     float3 wpos = mul(unity_CameraToWorld, float4(vpos, 1)).xyz;
    12.  
    13.     //Fetch shadow coordinates for cascade.
    14.     float4 coords = TransformWorldToShadowCoord(wpos);
    15.  
    16.     // Screenspace shadowmap is only used for directional lights which use orthogonal projection.
    17.     ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
    18.     half4 shadowParams = GetMainLightShadowParams();
    19.     return SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), coords, shadowSamplingData, shadowParams, false);
    20. }
    Code is based on Unity's own screen-space shadow pass https://github.com/Unity-Technologi...ersal/Shaders/Utils/ScreenSpaceShadows.shader

    It may be faster or more convenient to add the "Screen Space Shadows" render feature before your own, then use half SampleScreenSpaceShadowmap(float4 shadowCoord)(declared in ShaderLibrary/Shadows.hlsl) to sample the shadow map in screen-space, which will already be resolved
     
    Bodkin likes this.
  5. piter00999

    piter00999

    Joined:
    Jan 5, 2018
    Posts:
    19
    Wow, thanks for such a detailed answer :D! I guess it's time to tinker with it again.