Search Unity

[SRP] Light index must be a valid shadow casting light

Discussion in 'Shaders' started by adysoft, May 9, 2019.

  1. adysoft

    adysoft

    Joined:
    Mar 31, 2019
    Posts:
    1
    Hi,

    I am currently experimenting with SRP using this guide.

    I reached a point where I am not exactly sure what I am doing wrong.

    This is how my scene is setup:



    1 Camera, 1 Directional Light, 1 Cube, and 1 Plane.

    Here is my Pipeline:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3.  
    4. public class LightsAndShadowsRenderPipeline : RenderPipeline
    5. {
    6.     static int SunlightVectorId = Shader.PropertyToID("sunlightVector");
    7.  
    8.     private CommandBuffer _cameraCommandBuffer = new CommandBuffer() { name = "Render camera" };
    9.     private CommandBuffer _shadowCommandBuffer = new CommandBuffer() { name = "Render shadows" };
    10.     private RenderTexture _shadowMap;
    11.  
    12.     protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    13.     {
    14.         foreach(Camera camera in cameras)
    15.         {
    16.             Render(context, camera);
    17.         }
    18.     }
    19.  
    20.     private void Render(ScriptableRenderContext context, Camera camera)
    21.     {
    22.         BeginDrawShadows(context, camera, _shadowCommandBuffer);
    23.  
    24.         context.SetupCameraProperties(camera);
    25.  
    26.         ClearRenderTarget(context, camera, _cameraCommandBuffer);
    27.  
    28.         if (camera.TryGetCullingParameters(out ScriptableCullingParameters cullingParameters))
    29.         {
    30.             BeginDraw(context, _cameraCommandBuffer);
    31.  
    32.             context.DrawSkybox(camera);
    33.  
    34.             DrawRenderers(context, cullingParameters, _cameraCommandBuffer);
    35.  
    36.             EndDraw(context, _cameraCommandBuffer);
    37.  
    38.             context.Submit();
    39.         }
    40.  
    41.         EndDrawShadows();
    42.     }
    43.  
    44.     private void BeginDraw(ScriptableRenderContext context, CommandBuffer commandBuffer)
    45.     {
    46.         commandBuffer.BeginSample("Render Camera");
    47.         context.ExecuteCommandBuffer(_cameraCommandBuffer);
    48.         commandBuffer.Clear();
    49.     }
    50.  
    51.     private void EndDraw(ScriptableRenderContext context, CommandBuffer commandBuffer)
    52.     {
    53.         commandBuffer.EndSample("Render Camera");
    54.         context.ExecuteCommandBuffer(_cameraCommandBuffer);
    55.         commandBuffer.Clear();
    56.     }
    57.  
    58.     private void ClearRenderTarget(ScriptableRenderContext context, Camera camera, CommandBuffer commandBuffer)
    59.     {
    60.         CameraClearFlags clearFlags = camera.clearFlags;
    61.         commandBuffer.ClearRenderTarget((clearFlags & CameraClearFlags.Depth) != 0, (clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor);      
    62.     }
    63.  
    64.     private void BeginDrawShadows(ScriptableRenderContext context, Camera camera, CommandBuffer commandBuffer)
    65.     {
    66.         if (camera.TryGetCullingParameters(out ScriptableCullingParameters cullingParameters))
    67.         {
    68.             CullingResults cull = context.Cull(ref cullingParameters);
    69.  
    70.             _shadowMap = RenderTexture.GetTemporary(camera.pixelWidth, camera.pixelHeight, 16, RenderTextureFormat.Shadowmap);
    71.             _shadowMap.filterMode = FilterMode.Bilinear;
    72.             _shadowMap.wrapMode = TextureWrapMode.Clamp;
    73.  
    74.             commandBuffer.SetRenderTarget(_shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
    75.             commandBuffer.ClearRenderTarget(true, false, Color.clear, 1);
    76.  
    77.             commandBuffer.BeginSample("Render Shadows");
    78.             context.ExecuteCommandBuffer(commandBuffer);
    79.             commandBuffer.Clear();
    80.  
    81.             cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(0, 0, 1, Vector3.right, 512, cull.visibleLights[0].light.shadowNearPlane, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitdata);
    82.             commandBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);
    83.             context.ExecuteCommandBuffer(commandBuffer);
    84.             commandBuffer.Clear();
    85.  
    86.             var shadowDrawingSettings = new ShadowDrawingSettings(cull, 0) { splitData = shadowSplitdata };
    87.             shadowDrawingSettings.lightIndex = 0;
    88.             context.DrawShadows(ref shadowDrawingSettings);
    89.             context.ExecuteCommandBuffer(commandBuffer);
    90.             commandBuffer.Clear();
    91.  
    92.             commandBuffer.EndSample("Render Shadows");
    93.             context.ExecuteCommandBuffer(commandBuffer);
    94.             commandBuffer.Clear();
    95.         }
    96.     }
    97.  
    98.     private void EndDrawShadows()
    99.     {
    100.         if (_shadowMap)
    101.         {
    102.             RenderTexture.ReleaseTemporary(_shadowMap);
    103.             _shadowMap = null;
    104.         }
    105.     }
    106.  
    107.     private void DrawRenderers(ScriptableRenderContext context, ScriptableCullingParameters cullingParameters, CommandBuffer commandBuffer)
    108.     {
    109.         CullingResults cull = context.Cull(ref cullingParameters);
    110.  
    111.         SetLightingConstantBuffers(context, cull, commandBuffer);
    112.  
    113.         DrawingSettings drawingSettings = new DrawingSettings(new ShaderTagId("SRPDefaultUnlit"), new SortingSettings() { criteria = SortingCriteria.CommonOpaque });
    114.         FilteringSettings filteringSettings = FilteringSettings.defaultValue;
    115.         filteringSettings.renderQueueRange = RenderQueueRange.opaque;
    116.         context.DrawRenderers(cull, ref drawingSettings, ref filteringSettings);
    117.     }
    118.  
    119.     private void SetLightingConstantBuffers(ScriptableRenderContext context, CullingResults cull, CommandBuffer commandBuffer)
    120.     {
    121.         VisibleLight sunlight = cull.visibleLights[0];
    122.         Vector4 v = -sunlight.localToWorldMatrix.GetColumn(2);      
    123.  
    124.         commandBuffer.SetGlobalVector(SunlightVectorId, v);
    125.         context.ExecuteCommandBuffer(commandBuffer);
    126.         commandBuffer.Clear();
    127.     }
    128. }
    And my shader...

    Code (CSharp):
    1. Shader "My Shaders/LightsAndShadowsRP/Default"
    2. {
    3.     SubShader
    4.     {
    5.         Tags { "RenderType"="Opaque" }
    6.         LOD 100
    7.  
    8.         Pass
    9.         {
    10.             HLSLPROGRAM
    11.             #pragma vertex vert
    12.             #pragma fragment frag
    13.          
    14.             #include "Default.hlsl"
    15.  
    16.             ENDHLSL
    17.         }
    18.  
    19.         Pass
    20.         {
    21.             Tags { "LigthMode" = "ShadowCaster" }
    22.  
    23.             HLSLPROGRAM
    24.  
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.  
    28.             #include "Shadows.hlsl"
    29.  
    30.             ENDHLSL
    31.         }
    32.     }
    33. }
    34.  
    I only have 1 light in my scene. It's directional, with its Shadow Type set to "Hard Shadows".
    Yet, I get this "Light index must be a valid shadow casting light" when my command buffers are submitted.
    Any idea why?
    When I am looking at my Frame Debugger, I can only see the depth buffer being cleared for the shadow pass, but nothing else (no sphere draw).

     
    Last edited: May 9, 2019
  2. zjucaoyu97

    zjucaoyu97

    Joined:
    Jun 22, 2019
    Posts:
    2
    I got the same problem too...
     
  3. BattleAngelAlita

    BattleAngelAlita

    Joined:
    Nov 20, 2016
    Posts:
    400
    Fall in this problem too. The reason was that when you use SRP in unity 2018 unity hides shadow settings in quality settings window. And without enabling it shadows dosn't work. Just do QualitySettings.shadows = ShadowQuality.All
     
    N-E-S-T-O-R likes this.
  4. Virpark

    Virpark

    Joined:
    Oct 16, 2018
    Posts:
    1
    Hi.I setting this in MyPipline constructor, but isn't working,Where are you setup?
     
  5. zjucaoyu97

    zjucaoyu97

    Joined:
    Jun 22, 2019
    Posts:
    2
    I solved my problem which I just spell `SAMPLE_TEXTURE2D_SHADOW` to be `SAMPLER_TEXTURE2D_SHADOW` incorrectly in `Lit.hlsl` ...:(I correct it and everything to be ok
     
  6. IronManyx

    IronManyx

    Joined:
    May 7, 2017
    Posts:
    2
    I have the same problem and i set the "QualitySettings.shadows = ShadowQuality.All",but unity still error that no valid index light that cast shadow(frame debugger shows the shadows pass correct)
     
  7. daozang

    daozang

    Joined:
    Jun 25, 2019
    Posts:
    1
    you need check the
    VisibleLight.light.shadows != LightShadows.None. you can use the index of VisibleLights with light.shadows != LightShadows.None.
    NativeArray<VisibleLight> vLiNArr = pContext.cullingResults._UnityCullingResults.visibleLights;
    if (vLiNArr.Length > 0)
    {
    for (int i = 0; i < vLiNArr.Length; i++)
    {
    if (vLiNArr.light.shadows != LightShadows.None)
    {
    var shadowSettings = new ShadowDrawingSettings(pContext.cullingResults.UnityResults, i);
    }
     
  8. Aaron-B

    Aaron-B

    Joined:
    Sep 13, 2021
    Posts:
    1
    For anyone else who got directed to this post due to Googling the error while looking through the tutorial linked in the original post (i.e. "catlikecoding.com"). Make sure your lighting rendering code/pass only runs when this condition is true:
    Code (CSharp):
    1. if (
    2.     // The below line is optional if you're not following the tutorial.
    3.     ShadowedDirectionalLightCount < maxShadowedDirectionalLightCount &&
    4.     // The below is what will likely fix the issue generally.
    5.     light.shadows != LightShadows.None && light.shadowStrength > 0f &&
    6.     cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b)
    7. ) {
    8.     // Lighting rendering goes here.
    9. }
    That fixed it for me.