Search Unity

HDRP getting shadow attenuation

Discussion in 'High Definition Render Pipeline' started by echologin, Apr 8, 2020.

  1. echologin

    echologin

    Joined:
    Apr 11, 2010
    Posts:
    1,078
    So I can get main dir light in code for HDRP by using


    DirectionalLightData light = _DirectionalLightDatas[0];
    i_lightDir = -light.forward.xyz;
    i_color = light.color;


    Does anyone know how to get the shadow attenuation ?

    I am Trying to make this custom node that works in URP work the same in HDRP
     
  2. loveaoaaoa8

    loveaoaaoa8

    Joined:
    Jul 9, 2020
    Posts:
    1
    Want to know , too!
     
  3. nehvaleem

    nehvaleem

    Joined:
    Dec 13, 2012
    Posts:
    436
    I don't think it will be that easy, but It would open a lot of new possibilities. Keep up digging tho!
     
  4. SebLagarde

    SebLagarde

    Unity Technologies

    Joined:
    Dec 30, 2015
    Posts:
    934
    Hi, look for

    context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
    posInput.positionSS, posInput.positionWS, GetNormalForShadowBias(bsdfData),
    light.shadowIndex, L);

    in the code (lightloop.hlsl)

    however, the shadow aren't available while you are in the GBuffer pass (shader graph), as they are evaluated after it. So this will not help you.
     
  5. GamesbyJP

    GamesbyJP

    Joined:
    May 20, 2018
    Posts:
    62
    I'm in the same boat, trying to convert an existing cell shader from URP to HDRP, and it feels impossible without attenuation. I tried to set this value manually, but I'm not getting anything out of it.

    Is there a way of calculating this in real-time, even if it's an approximation?
     
  6. SebLagarde

    SebLagarde

    Unity Technologies

    Joined:
    Dec 30, 2015
    Posts:
    934
    Sorry, as explain above, the shadow are processed after the GBuffer pass (where you used shader graph) in HDRP, so you can't access it. And there is no way of approximating it, you need to render shadow map before Gbuffer in this case.
     
    GamesbyJP likes this.
  7. GamesbyJP

    GamesbyJP

    Joined:
    May 20, 2018
    Posts:
    62
    That's a shame, but thanks for the clear answer.
     
  8. Hysparions

    Hysparions

    Joined:
    Jan 7, 2019
    Posts:
    29
    Even in forward Rendering?
    Thank you
     
  9. SebLagarde

    SebLagarde

    Unity Technologies

    Joined:
    Dec 30, 2015
    Posts:
    934
    If you are forward only, you can indeed access it. But it is not an option we will support (as we need to maintain all pass + UX), your are on your own for this change.
     
  10. SebLagarde

    SebLagarde

    Unity Technologies

    Joined:
    Dec 30, 2015
    Posts:
    934
    Just to clarify. Lots of users want to do cell shading with, and thus get lighting information to remap it with a Tex1D Ramp.
    Will a hook to provide such a ramp enough for your use case or you need more than that? (i.e if we were adding a hook allowing to apply a ramp texture on the lighting, would this be enough? )
    Thanks for the detail.
     
    Lynial likes this.
  11. GamesbyJP

    GamesbyJP

    Joined:
    May 20, 2018
    Posts:
    62
    If we can hook up our own TEX ramp that'll atleast be better than what we have now. Best case scenario would be to have full access to the light information like in URP, but since that's not possible I think this is the second best solution.
     
  12. slime73

    slime73

    Joined:
    May 14, 2017
    Posts:
    107
    Hopefully that wouldn't be implemented in a way that always affects performance or always uses texture slots for the rest of us who don't use our own ramp. :)
     
  13. GodsKnight117

    GodsKnight117

    Joined:
    Mar 13, 2018
    Posts:
    43
    Hope someone figures this out soon, I would really love to use cell shading in my game.
     
  14. Schipunov

    Schipunov

    Joined:
    Apr 16, 2020
    Posts:
    1
    Also waiting for this
     
  15. bonickhausen

    bonickhausen

    Joined:
    Jan 20, 2014
    Posts:
    115
    Has there been any progress with this? I've been trying to implement Half Lambert shading into HDRP but it's been impossible so far.
     
  16. Lynial

    Lynial

    Joined:
    Jan 29, 2016
    Posts:
    1
    Hello, a ramp texture on the lighting would be good enough for my use case. Is that still something you're looking to implement?

    Cheers
     
    GamesbyJP likes this.
  17. bonickhausen

    bonickhausen

    Joined:
    Jan 20, 2014
    Posts:
    115
    Hey, any progress on this?
     
  18. bonickhausen

    bonickhausen

    Joined:
    Jan 20, 2014
    Posts:
    115
    Hiya! How's this coming up?
     
  19. JuanCecchetto

    JuanCecchetto

    Joined:
    May 18, 2015
    Posts:
    6
    Are there any updates on this?
     
  20. Just_Lukas

    Just_Lukas

    Joined:
    Feb 9, 2019
    Posts:
    34
    I'm working on a custom "Simple Lit" lighting model for HDRP (12.1.8) and since there is no usable documentation on HDRP's shaders nor detailed inner workings of the rendering pipeline I've decided to investigate this matter on my own and here's what I've found after several days of digging through the HDRP's shader code base mess:

    When talking about Lit material type in forward rendering mode the shadows are calculated in something called a LightLoop which is executed in ShaderPassForward.hlsl by following code:

    Code (CSharp):
    1. LightLoopOutput lightLoopOutput;
    2. LightLoop(V, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);

    Here's the include path: Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl

    The light loop evaluates each light in the scene and calculates Directional, Punctual and Enviromental contributions as well as shadows. To access these shadows you will need to execute the following code in your fragment program:

    Code (CSharp):
    1. // Gets the main light in the scene
    2. DirectionalLightData light = _DirectionalLightDatas[0];
    3.  
    4. float3 positionWS = posInput.positionWS;
    5. float3 lightDirWS = -light.forward;
    6.  
    7. // Samples the shadow map and returns shadow attenuation value for the current pixel
    8. float shadow = GetDirectionalShadowAttenuation(
    9.     InitShadowContext(),
    10.     posInput.positionSS,
    11.     positionWS,
    12.     GetNormalForShadowBias(bsdfData),
    13.     light.shadowIndex,
    14.     lightDirWS);

    upload_2023-1-14_17-48-9.png

    However when using the code above, HDRP generates ugly artifacts highlighted red while also generating proper shadow receiving from cube above highlighted green. I believe these "self shadowing" artifacts are caused either by shadow map compression or the PCF soft shadow filtering.

    These shadows will also be affected by HDRP's settings like enable / disable, shadow map resolution or cascades. What HDRP does to hide these artifacts is calculate standard diffuse (N dot L) lighting on top which results in following shadows:

    upload_2023-1-14_17-58-9.png

    There are still some artifacts visible but usually the intensity of these shadows are around 30% - 20% of this because of ambient lighting in your scene which will hide these ugly patterns, in fact if you look very closely on the HDRP/Lit material you will also see them.

    BUT these shadows only come from one directional light so you will have to calculate punctual and other by yourself + you will probably need implement other shadow controlling logic too such as Dimmer, Tint and so on.. Luckily for us the DirectionalLightData struct holds all this information:

    Code (CSharp):
    1. // Generated from UnityEngine.Rendering.HighDefinition.DirectionalLightData
    2. // PackingRules = Exact
    3. struct DirectionalLightData
    4. {
    5.     float3 positionRWS;
    6.     uint lightLayers;
    7.     float lightDimmer;
    8.     float volumetricLightDimmer;
    9.     float3 forward; // Negate this to get direction from vertex / pixel to light
    10.     int cookieMode;
    11.     float4 cookieScaleOffset;
    12.     float3 right;
    13.     int shadowIndex;
    14.     float3 up;
    15.     int contactShadowIndex;
    16.     float3 color; // Light color tint ofc
    17.     int contactShadowMask;
    18.     float3 shadowTint; // Only necessary when you plan to have colored shadows, but usually this is pure black
    19.     float shadowDimmer; // Important variable to implement
    20.     float volumetricShadowDimmer;
    21.     int nonLightMappedOnly;
    22.     real minRoughness;
    23.     int screenSpaceShadowIndex;
    24.     real4 shadowMaskSelector;
    25.     float2 cascadesBorderFadeScaleBias;
    26.     float diffuseDimmer; // Dimmers for when you decide to calculate your own lighting model like I do
    27.     float specularDimmer;
    28.     float penumbraTint;
    29.     float isRayTracedContactShadow;
    30.     float distanceFromCamera;
    31.     float angularDiameter;
    32.     float flareFalloff;
    33.     float flareCosInner;
    34.     float flareCosOuter;
    35.     float __unused__;
    36.     float3 flareTint;
    37.     float flareSize;
    38.     float3 surfaceTint;
    39.     float4 surfaceTextureScaleOffset;
    40. };
    Above I've commented some variables that I consider as important to implement. This is what I know so far the forward lighting process is very complicated and basically lies in following scripts ordered by calling hierarchy:
    • ShaderPassForward.hlsl
    • LightLoop.hlsl
    • Lit.hlsl or other lighting type that you will use
    • SurfaceShading.hlsl
    I hope this post helps all wariors like me who were trying to dig through the shader mess, gl! :D