Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question HDRP SHADOW_ATTENUATION always 1 in Shader

Discussion in 'Graphics Experimental Previews' started by KYL3R, Aug 3, 2020.

  1. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    Hi there. I am using Unity 2019.4 LTS.

    I want to receive shadows.

    What I tried:

    I got shadows working by adding `FallBack "HDRP/Lit"` but I cannot receive shadows.

    shadow attenuation is always 1 in my fragment shader.
    Code (CSharp):
    1. SHADOW_ATTENUATION(i)
    As you can see, world space coordinates seem to work using:
    Code (CSharp):
    1. col.r = i.worldPosThing.x / 10;
    2. col.g = i.worldPosThing.y / 10;
    3. col.b = i.worldPosThing.z / 10;

    But this is always white (and LIGHT_ATTENUATION is black...)

    Code (CSharp):
    1. col.r = SHADOW_ATTENUATION(i);
    2. col.g = SHADOW_ATTENUATION(i);
    3. col.b = SHADOW_ATTENUATION(i);




    Question: Can anybody aid me on how to receive shadows in hdrp?
     
  2. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    247
    Because LIGHT_ATTENUATION is a legacy pipeline macros. There isnt a macros like that in HDRP. For forward you're supposed to use LightLoop function (com.unity.render-pipelines.high-definition\Runtime\Lighting\LightLoop\LightLoop.hlsl), which calculates all the lighting/shadowing.

    Also you shouldnt use forward for drawing opaque things anyway, and instead use deferred ("LightMode" = "GBuffer"). With deferred you do not need to worry about lighting at all, since its gonna be lit as a part of regular deferred lighting path, you just need to supply the surface data (albedo, normals, smoothness, specular, etc.)
     
  3. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    @customphase thanks replying. I now used this:

    Code (CSharp):
    1. Tags { "LIGHTMODE" = "GBuffer" "QUEUE" = "Geometry+0" "RenderType" = "HDLitShader" "RenderPipeline" = "HDRenderPipeline" }
    But my meshes are a transparent now, also when I get too close or too far away, they disappear and it looks like the buffer isn't clearing correctly...






    I simplified my shader to this, just to replicate the issue:

    Code (CSharp):
    1. Shader "Custom/Grass" {
    2.     Properties{
    3.         _TintColor1("Tint Color 1", Color) = (1, 1, 1, 1)
    4.         _TintColor2("Tint Color 2", Color) = (1, 1, 1, 1)
    5.         _ColorHeight("Color Height", Range(0, 1)) = .3
    6.     }
    7.  
    8.     SubShader{
    9.        
    10.         Pass {
    11.             Tags { "LIGHTMODE" = "GBuffer" "QUEUE" = "Geometry+0" "RenderType" = "HDLitShader" "RenderPipeline" = "HDRenderPipeline" }
    12.             //ZWrite On
    13.             //Cull Back
    14.             CGPROGRAM
    15.  
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.             #pragma target 3.0
    19.             #pragma multi_compile_instancing
    20.  
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct Input {
    24.                 float4 vertex: POSITION;
    25.                 float localPos : TEXCOORD0;
    26.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    27.             };
    28.  
    29.             struct v2f {
    30.                 float4 vertex: SV_POSITION;
    31.                 float localPos : TEXCOORD0;
    32.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    33.             };
    34.  
    35.             float4 _TintColor1;
    36.             float4 _TintColor2;
    37.             float _ColorHeight;
    38.  
    39.             UNITY_INSTANCING_BUFFER_START(Props)
    40.             UNITY_DEFINE_INSTANCED_PROP(fixed4, _CollisionBending)
    41.             UNITY_INSTANCING_BUFFER_END(Props)
    42.  
    43.             v2f vert(Input input) {
    44.                 v2f o;
    45.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
    46.                 UNITY_SETUP_INSTANCE_ID(input);
    47.  
    48.                 o.localPos = input.vertex.y;
    49.                 o.vertex = UnityObjectToClipPos(input.vertex);
    50.  
    51.                 return o;
    52.             }
    53.  
    54.             fixed4 frag(v2f i) : SV_Target {
    55.                 fixed4 col = lerp(_TintColor1, _TintColor2, dot(_ColorHeight, i.localPos.x));
    56.                 col.a = 1;
    57.                 return col;
    58.             }
    59.             ENDCG
    60.         }
    61.     }
    62.         FallBack "HDRP/Lit"
    63. }
     
  4. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    247
    You also need a DepthOnly pass and a ShadowCaster pass.

    Also im pretty sure that tags are case-sensitive, and it should be LightMode, not LIGHTMODE, and Queue, not QUEUE.

    Also Queue and RenderType tags are subshader tags, not pass tags.
     
  5. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    @customphase Thanks, I will try to implement the additional passes.
    I usually use the Tags case-sensitive, but I copied this from Unity. I created a Graph, clicked "compile and show code". It's over 1 million lines, so I'm glad you help me with this. But to get the syntax for some things it's helpful to look into the generated code.
     
  6. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    @customphase I had no luck implementing the DepthOnly pass, it still looks the same :/ No errors showing, it's not pink. I'm a bit lost without any working reference...

    Can you take a look?

    Code (CSharp):
    1. Shader "Custom/Grass" {
    2.     Properties{
    3.         _TintColor1("Tint Color 1", Color) = (1, 1, 1, 1)
    4.         _TintColor2("Tint Color 2", Color) = (1, 1, 1, 1)
    5.         _ColorHeight("Color Height", Range(0, 1)) = .3
    6.     }
    7.  
    8.     SubShader{
    9.        
    10.         Pass {
    11.             Tags { "LightMode" = "GBuffer" "Queue" = "Geometry+0" "RenderType" = "HDLitShader" "RenderPipeline" = "HDRenderPipeline" }
    12.             //ZWrite On
    13.             //Cull Back
    14.             CGPROGRAM
    15.  
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.             #pragma target 3.0
    19.             #pragma multi_compile_instancing
    20.  
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct Input {
    24.                 float4 vertex: POSITION;
    25.                 float localPos : TEXCOORD0;
    26.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    27.             };
    28.  
    29.             struct v2f {
    30.                 float4 vertex: SV_POSITION;
    31.                 float localPos : TEXCOORD0;
    32.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    33.             };
    34.  
    35.             float4 _TintColor1;
    36.             float4 _TintColor2;
    37.             float _ColorHeight;
    38.  
    39.             UNITY_INSTANCING_BUFFER_START(Props)
    40.             UNITY_DEFINE_INSTANCED_PROP(fixed4, _CollisionBending)
    41.             UNITY_INSTANCING_BUFFER_END(Props)
    42.  
    43.             v2f vert(Input input) {
    44.                 v2f o;
    45.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
    46.                 UNITY_SETUP_INSTANCE_ID(input);
    47.  
    48.                 o.localPos = input.vertex.y;
    49.                 o.vertex = UnityObjectToClipPos(input.vertex);
    50.  
    51.                 return o;
    52.             }
    53.  
    54.             fixed4 frag(v2f i) : SV_Target {
    55.                 fixed4 col = lerp(_TintColor1, _TintColor2, dot(_ColorHeight, i.localPos.x));
    56.                 col.a = 1;
    57.                 return col;
    58.             }
    59.             ENDCG
    60.         }
    61.         Pass {
    62.             Name "DepthOnly"
    63.             Tags { "LightMode" = "DepthOnly" "Queue" = "Geometry+0" "RenderType" = "HDLitShader" "RenderPipeline" = "HDRenderPipeline" }
    64.             ColorMask 0
    65.             ZWrite On
    66.  
    67.             HLSLPROGRAM
    68.  
    69.             #pragma target 3.5
    70.  
    71.             #pragma multi_compile_instancing
    72.             #include "UnityCG.cginc"
    73.  
    74.             #pragma vertex DepthOnlyPassVertex
    75.             #pragma fragment DepthOnlyPassFragment
    76.  
    77.             struct VertexInput {
    78.                 float4 pos : POSITION;
    79.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    80.             };
    81.  
    82.             struct VertexOutput {
    83.                 //float4 clipPos : SV_POSITION;
    84.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    85.             };
    86.  
    87.             VertexOutput DepthOnlyPassVertex(VertexInput input) {
    88.                 VertexOutput output;
    89.                 UNITY_SETUP_INSTANCE_ID(input);
    90.                 UNITY_TRANSFER_INSTANCE_ID(input, output);
    91.                 float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
    92.                 //output.clipPos = mul(unity_MatrixVP, worldPos);
    93.                 return output;
    94.             }
    95.  
    96.             float4 DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
    97.                 //UNITY_SETUP_INSTANCE_ID(input);
    98.                 return 0;
    99.             }
    100.  
    101.             ENDHLSL
    102.         }
    103.     }
    104.     FallBack "HDRP/Lit"
    105. }
     
  7. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    247
    Why did you comment out clip position output in the depth only pass? Clip position is absolutely required in ANY pass output, its what defines where the pixels would be drawn. The depthOnly pass should basically be a copy of a gBuffer pass, just with
    return 0;
    in the fragment program.
     
  8. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    Hey @customphase - I got a bit of progress.

    I added the "Stencil { ... }" part. I got the mesh visible and also shadows (yay!) but the effect of shine-through is still there (the buffers not clearing correctly)





    Code (CSharp):
    1. Shader "Custom/Grass" {
    2.     Properties{
    3.         _TintColor1("Tint Color 1", Color) = (1, 1, 1, 1)
    4.         _TintColor2("Tint Color 2", Color) = (1, 1, 1, 1)
    5.         _ColorHeight("Color Height", Range(0, 1)) = .3
    6.  
    7.         _StencilRef("Stencil Ref Value", Range(0, 100)) = 10
    8.         _StencilWriteMask("Stencil WriteMask Value", Range(0, 100)) = 14
    9.         _StencilRefDepth("Stencil Ref Value Depth", Range(0, 100)) = 8
    10.         _StencilWriteMaskDepth("Stencil WriteMask Value Depth", Range(0, 100)) = 14
    11.     }
    12.  
    13.     SubShader{
    14.        
    15.         Pass {
    16.             Name "GBuffer"
    17.             Tags { "LightMode" = "GBuffer" }
    18.             ZWrite On
    19.             Stencil {
    20.                 Ref [_StencilRef]
    21.                 WriteMask [_StencilWriteMask]
    22.                 Comp Always
    23.                 Pass Replace
    24.                 // Fail Keep
    25.                 // ZFail Keep
    26.             }
    27.  
    28.             HLSLPROGRAM
    29.  
    30.             #pragma target 3.5
    31.  
    32.             #pragma multi_compile_instancing
    33.             #include "UnityCG.cginc"
    34.  
    35.             #pragma vertex DepthOnlyPassVertex
    36.             #pragma fragment DepthOnlyPassFragment
    37.  
    38.             struct VertexInput {
    39.                 float4 pos : POSITION;
    40.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    41.             };
    42.  
    43.             struct VertexOutput {
    44.                 float4 clipPos : SV_POSITION;
    45.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    46.             };
    47.  
    48.             VertexOutput DepthOnlyPassVertex(VertexInput input) {
    49.                 VertexOutput output;
    50.                 UNITY_SETUP_INSTANCE_ID(input);
    51.                 UNITY_TRANSFER_INSTANCE_ID(input, output);
    52.                 float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
    53.                 output.clipPos = mul(unity_MatrixVP, worldPos);
    54.                 return output;
    55.             }
    56.  
    57.             float4 DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
    58.                 UNITY_SETUP_INSTANCE_ID(input);
    59.                 return float4(.4,1,.4,1);
    60.             }
    61.  
    62.             ENDHLSL
    63.         }
    64.         Pass {
    65.             Name "DepthOnly"
    66.             Tags { "LightMode" = "DepthOnly" "Queue" = "Geometry+0" "RenderType" = "Opaque" "RenderPipeline" = "HDRenderPipeline" }
    67.             ColorMask 0
    68.             ZWrite On
    69.             Stencil {
    70.                 Ref[_StencilRefDepth]
    71.                 WriteMask[_StencilWriteMaskDepth]
    72.                 Comp Always
    73.                 Pass Replace
    74.                 // Fail Keep
    75.                 // ZFail Keep
    76.             }
    77.  
    78.  
    79.  
    80.             HLSLPROGRAM
    81.  
    82.             #pragma target 3.5
    83.  
    84.             #pragma multi_compile_instancing
    85.             #include "UnityCG.cginc"
    86.  
    87.             #pragma vertex DepthOnlyPassVertex
    88.             #pragma fragment DepthOnlyPassFragment
    89.  
    90.             struct VertexInput {
    91.                 float4 pos : POSITION;
    92.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    93.             };
    94.  
    95.             struct VertexOutput {
    96.                 float4 clipPos : SV_POSITION;
    97.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    98.             };
    99.  
    100.             VertexOutput DepthOnlyPassVertex(VertexInput input) {
    101.                 VertexOutput output;
    102.                 UNITY_SETUP_INSTANCE_ID(input);
    103.                 UNITY_TRANSFER_INSTANCE_ID(input, output);
    104.                 float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
    105.                 output.clipPos = mul(unity_MatrixVP, worldPos);
    106.                 return output;
    107.             }
    108.  
    109.             float4 DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
    110.                 UNITY_SETUP_INSTANCE_ID(input);
    111.                 return 0;
    112.             }
    113.  
    114.             ENDHLSL
    115.         }
    116.     }
    117.     FallBack "HDRP/Lit"
    118. }
     
  9. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    247
    @KYL3R You didnt fill out the GBuffer correctly. GBuffer consists of multiple render targets, you should check out the fragment program from
    com.unity.render-pipelines.high-definition\Runtime\RenderPipeline\ShaderPass\ShaderPassGBuffer.hlsl
    and see how they handle GBuffer there, how to correctly write and encode data into it.
     
  10. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
  11. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    I looked into the FrameDebugger and saw: Diffuse looks good, but my shader didn't write anything into the specular buffer. I only found this out, because you told me about the Render Targets, so I understood what these are for:


    So I changed my fragment shader to return a struct instead of a float4.
    Code (CSharp):
    1. struct FragmentOutput {
    2.     float4 gBuffer0 : SV_Target0;
    3.     float4 gBuffer1 : SV_Target1;
    4.     float4 gBuffer2 : SV_Target2;
    5.     float4 gBuffer3 : SV_Target3;
    6. };
    Got this bit from here:
    https://catlikecoding.com/unity/tutorials/rendering/part-13/

    I'm not completely there, but the "buffer shining through mesh"-artifacts (as seen in the video I posted) are gone :)




    So thanks for the hints @customphase :)

    If anyone is interested:
    Code (CSharp):
    1. Shader "Custom/Grass" {
    2.     Properties{
    3.         _TintColor1("Tint Color 1", Color) = (1, 1, 1)
    4.         _TintColor2("Tint Color 2", Color) = (1, 1, 1)
    5.         _ColorHeight("Color Height", Range(0, 1)) = .3
    6.  
    7.         _StencilRef("Stencil Ref Value", Range(0, 100)) = 10
    8.         _StencilWriteMask("Stencil WriteMask Value", Range(0, 100)) = 14
    9.         _StencilRefDepth("Stencil Ref Value Depth", Range(0, 100)) = 8
    10.         _StencilWriteMaskDepth("Stencil WriteMask Value Depth", Range(0, 100)) = 14
    11.  
    12.  
    13.         _SpecularRGB("Specular Color", Color) = (1, 1, 1)
    14.         _RoughnessValue("Roughness Value", Range(0,1)) = 0.5
    15.     }
    16.  
    17.     SubShader{
    18.      
    19.         Pass {
    20.             Name "GBuffer"
    21.             Tags { "LightMode" = "GBuffer" }
    22.             ZWrite Off
    23.             Stencil {
    24.                 Ref [_StencilRef]
    25.                 WriteMask [_StencilWriteMask]
    26.                 Comp Always
    27.                 Pass Replace
    28.             }
    29.  
    30.             HLSLPROGRAM
    31.  
    32.             #pragma target 3.5
    33.  
    34.             #pragma multi_compile_instancing
    35.             #include "UnityCG.cginc"
    36.  
    37.             #pragma vertex DepthOnlyPassVertex
    38.             #pragma fragment DepthOnlyPassFragment
    39.  
    40.             struct VertexInput {
    41.                 float4 pos : POSITION;
    42.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    43.             };
    44.  
    45.             struct VertexOutput {
    46.                 float4 clipPos : SV_POSITION;
    47.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    48.             };
    49.  
    50.             float4 _TintColor1;
    51.             float4 _TintColor2;
    52.             float _ColorHeight;
    53.  
    54.             float3 _SpecularRGB;
    55.             float _RoughnessValue;
    56.  
    57.             VertexOutput DepthOnlyPassVertex(VertexInput input) {
    58.                 VertexOutput output;
    59.                 UNITY_SETUP_INSTANCE_ID(input);
    60.                 UNITY_TRANSFER_INSTANCE_ID(input, output);
    61.                 float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
    62.                 output.clipPos = mul(unity_MatrixVP, worldPos);
    63.                 return output;
    64.             }
    65.  
    66.             struct FragmentOutput {
    67.                 float4 gBuffer0 : SV_Target0;
    68.                 float4 gBuffer1 : SV_Target1;
    69.                 float4 gBuffer2 : SV_Target2;
    70.                 float4 gBuffer3 : SV_Target3;
    71.             };
    72.          
    73.  
    74.             FragmentOutput DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
    75.                 UNITY_SETUP_INSTANCE_ID(input);
    76.                 FragmentOutput output;
    77.                 float4 albedo = lerp(_TintColor1, _TintColor2, _ColorHeight);
    78.                 output.gBuffer0.rgb = albedo; // Diffuse (RGB), unused (A)
    79.                 float3 specular_roughness = float4(_SpecularRGB.r, _SpecularRGB.g, _SpecularRGB.b, _RoughnessValue);
    80.                 output.gBuffer1.rgb = specular_roughness; // specular (RGB) Roughness (A)
    81.                 output.gBuffer2.rgb = float4(0, 0, 0, 0); // world space normal?
    82.                 output.gBuffer3.rgb = float4(0, 0, 0, 0); // emission + lighting + lightmaps + reflection probes buffer...
    83.  
    84.                 return output;
    85.             }
    86.  
    87.             ENDHLSL
    88.         }
    89.         Pass {
    90.             Name "DepthOnly"
    91.             Tags { "LightMode" = "DepthOnly" "Queue" = "Geometry+0" "RenderType" = "Opaque" "RenderPipeline" = "HDRenderPipeline" }
    92.             ColorMask 0
    93.             ZWrite On
    94.             Stencil {
    95.                 Ref[_StencilRefDepth]
    96.                 WriteMask[_StencilWriteMaskDepth]
    97.                 Comp Always
    98.                 Pass Replace
    99.             }
    100.  
    101.             HLSLPROGRAM
    102.  
    103.             #pragma target 3.5
    104.  
    105.             #pragma multi_compile_instancing
    106.             #include "UnityCG.cginc"
    107.  
    108.             #pragma vertex DepthOnlyPassVertex
    109.             #pragma fragment DepthOnlyPassFragment
    110.  
    111.             struct VertexInput {
    112.                 float4 pos : POSITION;
    113.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    114.             };
    115.  
    116.             struct VertexOutput {
    117.                 float4 clipPos : SV_POSITION;
    118.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    119.             };
    120.  
    121.             VertexOutput DepthOnlyPassVertex(VertexInput input) {
    122.                 VertexOutput output;
    123.                 UNITY_SETUP_INSTANCE_ID(input);
    124.                 UNITY_TRANSFER_INSTANCE_ID(input, output);
    125.                 float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
    126.                 output.clipPos = mul(unity_MatrixVP, worldPos);
    127.                 return output;
    128.             }
    129.  
    130.             float4 DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
    131.                 UNITY_SETUP_INSTANCE_ID(input);
    132.                 return 0;
    133.             }
    134.  
    135.             ENDHLSL
    136.         }
    137.     }
    138.     FallBack "HDRP/Lit"
    139. }
     
    Last edited: Aug 15, 2020
  12. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    247
    @KYL3R That tutorial is for the regular default pipeline. HDRP uses different GBuffer data layout:

    Code (CSharp):
    1. //FeatureName   Standard
    2. //GBuffer0      baseColor.r,    baseColor.g,    baseColor.b,    specularOcclusion
    3. //GBuffer1      normal.xy (1212),   perceptualRoughness
    4. //GBuffer2      f0.r,   f0.g,   f0.b,   featureID(3) / coatMask(5)
    5. //GBuffer3      bakedDiffuseLighting.rgb
    This is from
    com.unity.render-pipelines.high-definition\Runtime\Material\Lit\Lit.hlsl
    .

    And btw, they pack normals and featureID/coatMask in a special way, again, you need to look into the source code of the HDRP shaders, youre not gonna go far without it.
     
  13. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    @customphase Thanks again. I only wish there was a proper HDRP Documentation, explaining such things. But I guess reading the source code has to work for now.
     
  14. KYL3R

    KYL3R

    Joined:
    Nov 16, 2012
    Posts:
    141
    hmm. Including "common.hlsl" or "NormalBuffer.hlsl" give me some new problems like "xy is already defined" or "real3 not defined" which means I need more includes, leading to more problems...

    - In the End I copied "EncodeIntoNormalBuffer" and the required functions: BitFieldInsert, CopySign, PackNormalOctQuadEncode and PackFloat2To888.

    Now it works, the normals look similar to the rest of the scene (even though they look a bit strange because of the packing)



    And the grass now looks more "round" because of the lights working properly.


    But it's still black when the directional light is blocked by a cube. So... how come other objects are brighter than black in the shadows? Is this still related to my shader?
    Do you have another hint, @customphase? Thanks in advance.

    btw. a point light seems to work as well. https://i.imgur.com/02Uff8r.mp4



    edit: Nevermind, apparently gBuffer2 (xyz) is shadow-color. I changed it from 0,0,0 to a value and now I have shadows working.
     
    Last edited: Nov 7, 2020
    customphase likes this.