Search Unity

Depth pass (Shadow Pass) only active when Lights are Active

Discussion in 'Shaders' started by Atair, Feb 20, 2018.

  1. Atair

    Atair

    Joined:
    Oct 16, 2015
    Posts:
    42
    I am trying to get my point cloud shader to work with Volumetric effects..
    And while all the Depthtexture / pass business is really hard to grasp, i managed to get it to work by basically copy pasting my shader pass with "LightMode"="ShadowCaster".

    Now the Depth Texture is generated (deferred mode), but only works once a directional light casts shadows.

    Any way to force it to work without? I dont need light, just a working depth buffer so other shaders can sample it.

    Or even better - what is the fastest way to make my shader write into the depth buffer, no lights, normals or anything. just color and depth.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Yes, set the depth texture mode on the camera.
    https://docs.unity3d.com/Manual/SL-CameraDepthTexture.html

    If you're rendering using the deferred render path? Write a basic deferred shader. The fact you're using deferred and you needed the shadowcaster for your object to show up in the depth texture means your shader is getting rendered as part of the forward pass. Unity will render the shadowcaster pass of opaque queue objects into the deferred's gbuffer to fill out the depth texture.
     
    jhughes2112 likes this.
  3. Atair

    Atair

    Joined:
    Oct 16, 2015
    Posts:
    42
    thanks - it works! Had to put the DepthTextureMode.Depth in Awake.. was in Start before and it did not work.
    Any way to make it work in the editor?
    Also the help file says: 'Camera inspector indicates when a camera is rendering a depth or a depth+normals texture' - where does it do that?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    If you select the camera it will show the depth texture mode in the inspector, if set, at the bottom of the camera component. I believe you can set the depth texture mode in editor using [ExecuteInEditMode], though I don't remember if it gets serialized (saved) or not.
     
  5. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    This is a top hit on Google, but I don't fully understand bgolus's statement:

    ... I'm guessing the implicit text is "Yes, but this only works in Deferred mode, where you can set the depth texture mode on the camera"

    EDIT: in all this, I mean "Camera depth texture", I was being sloppy.

    In Forward mode:
    - Without lights in scene, Depth buffer is never filled-in by Unity
    - Setting the depth-mode of camera has no effect
    - Adding a single light to the scene causes Unity to fill-in the depth buffer
     
    Last edited: Oct 9, 2019
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    First, depth buffer != camera depth texture. Minor pedantic quibble, but potentially important. If we're talking about the depth texture accessed by shaders via the _CameraDepthTexture texture uniform, then we're talking about the camera depth texture and not the depth buffer.

    Second, when using the built in forward rendering path, setting the depth mode absolutely works. I've shipped several projects over the last 7 years using Unity that have all needed the depth texture in some fashion, and all but one have used the forward rendering path. However I wonder if you're getting confused by the "Depth" you'll see in the inspector when selecting the camera, which isn't the same thing. The inspector exposed depth is the order that camera renders in relative to other cameras in the scene. There is no way to set the depth texture mode on a camera component from the default inspector, it has to be set via a c# script.
    Code (CSharp):
    1. // SetCameraDepthTextureMode.cs
    2. using UnityEngine;
    3.  
    4. [RequireComponent(typeof(Camera))]
    5. [ExecuteInEditMode] // optional if you want to force this on in edit mode too
    6. public class SetCameraDepthTextureMode : MonoBehaviour
    7. {
    8.     [SerializeField] private DepthTextureMode depthTextureMode = DepthTextureMode.Depth;
    9.  
    10.     void OnEnable()
    11.     {
    12.         GetComponent<Camera>().depthTextureMode |= depthTextureMode;
    13.     }
    14. }
    If you don't have the depth texture mode set on the camera component, just having a light will not fill in the depth texture. It very specifically has to be a directional light with shadows enabled, and the project has to be using cascaded shadow maps. This means a shadow casting directional light on mobile, which does not use cascaded shadow maps, will not enable the depth texture. Nor will any point or spot lights regardless of their shadow casting setting. This is purely an artifact of Unity's screen space shadows using the camera depth texture. Similarly enabling soft particles will also force the camera depth texture to be rendered as this feature also uses it.
     
    mouurusai likes this.
  7. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Yep, I meant Camera depth texture - thank you, I was being sloppy there - and I interpreted OP's post to be only about that (possibly misinterpreted?).

    My experience (tested extensively in 2019.2, seems to be same in 2018.3 but less thoroughly tested):

    1. Your code above (which I previously used regularly in 5.x and 2017 IIRC) is not necessary any more, but also will NOT work in situations where Unity has decided to disable/ignore the Camera depth texture - e.g. if you turn off scene lighting in the Editor (I spoke to them about this at Unite, and it seems like this is considered a bug, although it's low priority). Interestingly, the "this camera is rendering a depth texture" message will still display if you use the code above, but without it the message no longer displays AND YET the depth texture is created perfectly fine. I'm not sure what's going on there :).

    2. My exact problem is the "if someone removes the last shadow-generating light, the depth texture vanishes - and my shader stops working in strange ways (because it cannot detect the presence/absence of the texture)". This is a huge problem, and my google searches were looking for a way to override that and force Unity to generate a depth texture.

    3. ...as a secondary problem, I so far cannot find a way to reliably detect if Unity is or is not filling-in the depth texture. Unity appears to have no way to tell you the number of lights being rendered in scene. You can query each light-slot, but they return identical results for "no light present" and "light present but configured to be black".

    (my current hack is: tell my developers "if you create a light that is black and 0 alpha, then you're weird, and ... everything will break. Don't do that", and I interpret the presence of a float4(0,0,0,0) light in the [0] light slot to mean "this scene has no shadow-generating light". In scripts, I'm also doing things like scanning the scene for lights based on Component, but that's not much help inside the shader (I'm hoping to avoid spamming the shader with script callbacks to tell it "oh no, there's no lights!"))
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Oh, wait, are you talking about URP or HDRP here? There is no "zero light slot" for the built in rendering paths since they're multi-pass renderers and never expose a light list anywhere (even the deferred renderer renders each light individually).

    This is all about the built in rendering paths. If you're using the SRPs, I can totally see that being a bug.
     
  9. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Good question :). No, I'm not on to SRPs yet, but I'm trying to find ways to write shader code for old rendering system with minimal changes needed to also support SRPs going forwards.

    What I meant by talking about "light-slots" was the built-in shader variables, that Unity fills-in with data about the lights in scene, and are accessible within a shader to do your own custom lighting calculations (with or without re-using sub-parts of Unity's lighting). They were first described to me as slots brcause of the way they contain a bunch of lights in an actual array, or a sort-of array, style (each successive pass gets the different light-data coming through in the "slot") - apologies if that's the wrong terminology, it just stuck with me.

    e.g.:

    * _WorldSpaceLightPos0
    * _LightColor0
    * unity_LightColor
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The unity_LightColor array was used for vertex lighting only. Only non-important point lights will show up there, and only in the forward base pass. All per-pixel lights will be rendered one at a time and be represented by the _LightColor0 value. If you don't have any important, shadow casting directional lights, you can get a _LightColor0 of 0,0,0. Also, AFAIK the alpha value for both the _LightColor0 and unity_LightColor is always 0. Since sometime mid Unity 5.0 it also only held data for up to 4 lights as the 8 light version (which also supported spot lights) was deprecated, and I think completely dead as of 2018?

    Still, I tried to recreate the problem of having no depth texture in scenes with no lights and could not reproduce it here. Setting the depth texture mode on the camera has always fixed it for me on past and current projects, even in scenes with no lights (like loading scenes etc.), and the last project we shipped is using 2018.2. Could be a 2019 bug though.
     
  11. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    (brief update: I'm fairly sure about this problem in 2019, but it's a minor nuisance compared to my other issues with _CameraDepthTexture and friends, so I'm currently trying to get those figured out, and a small, clean, simple scene put together where I can verify this and share the scene for others to try. But I'm currently dying trying to get queues + depthtextures + shadows to all work at once. Hahahaha. Sob)
     
  12. lgarczyn

    lgarczyn

    Joined:
    Nov 23, 2014
    Posts:
    68
    Appears to be fixed in 2020, even in the editor camera if you set Camere.current to depth mode, but make sure that any render texture actually has a depth buffer.