Search Unity

Unity 5 Lighting, Shadows, Coordinates and stuff - Shader Pro needed

Discussion in 'Shaders' started by MaT227, Dec 30, 2015.

  1. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Hi everyone,
    The title seems a bit vague but I couldn't find a way to sum up my questioning.

    I've made some tests and I found out that that every lights and associated shadows data are very different depending of their types (point, directional, etc.). Just to set-up my configuration, I am talking in forward rending mode (which I think doesn't influence shadow calculation) and linear color space.

    I found how to access the shadow map of, I think, every light type by using the defines such as SHADOW_ATTENUATION(a) or directly the _ShadowMapTexture, everything is located in the built-in shaders.
    (By the way, shadows of spot and point lights are really not smooth any idea why ? But this is off-topic)

    But I am wondering how could I access the depth of those lighting type. I found a way to access it for the spot light this way : _ShadowCoord.z which gives the depth scaled with _ShadowCoord.w, which could be considered to the far plane, but am I right ?

    How could I do the same for the other light types such as directional or point lights ? For the moment I am stuck with directional lights, any clues ?
    Because if I try to access the depth for a directional light by using _ShadowCoord.z it seems that it's more related to the depth view and not the light. Here I am, totally stuck with this directional lights. :)

    So, I am calling for the lighting, shadows and shaders super Heroes if they could help me. :)
     
  2. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Any pro or somebody that might know how to retrieve the deph from directional lights ?
     
  3. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    There's no easy way to do that, since currently on PC/consoles directional light shadows are done in "screenspace" way - shadows are gathered into screenspace buffer, and then later on there's no access to original directional light shadows anymore.

    There's indirect access to the directional light's shadowmap, that only works if you have one directional light with shadows. This works by setting shadowmap as a global shader property right after rendering it, but before the screenspace shadows are calculated, via a Light command buffer. As far as I know, the Blacksmith volumetric scattering effect (AssetStore package, blog post) uses that technique.
     
  4. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Thank you very much @Aras, I'll investigate !

    Edit : The aim is to calculate transmittance the same way Jorge Jimenez do it.
     
  5. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Sorry to bother you again but I have another question concerning this topic @Aras.

    As I can retrieve the shadowmap now thank to the Blacksmith volumetric scattering effect but is there a way to access the directional light view matrix and light projection matrix in forward rendering base pass as it seems that _LightMatrix0 is empty.

    Does the trick still consists of creating a camera and creating the matrix manually ?
     
  6. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Not sure to be honest. How does the blacksmith demo package do it? It needs to know the light view/projection matrix somehow, in order to be able to do marching through the shadowmap for volumetric effect.
     
  7. DHein

    DHein

    Joined:
    Jan 26, 2016
    Posts:
    38
    Currently, I am encountering the same problem, as I need to know the view/projection matrix of a certain directional light. I checked the Blacksmith demo pack, but couldn't find any hint how the matrix can be accessed. Apparently they still use the UNITY_SAMPLE_SHADOW macro and not a custom shadow mapping algorithm? It seems to me that the only way to access the matrix is by using the built-in variable _LightMatrix0 (declared in AutoLight.cginc). The problem here is that it is only accessable in forward and deferred rendering in cg code, but NOT in the script or ComputeShaders, which is what I need. @Aras, sorry for bringing up an older topic again, but do you know any way to pass the matrix information from the _LightMatrix0 variable to C# scripts, in order forward it to compute shaders?
     
  8. Avol

    Avol

    Joined:
    May 27, 2016
    Posts:
    95
    I found a way todo so. Basically create a 7 pixel rgbahalf or float texture and read out those projection matrices in fragment shader. Store it to that texture and later on sample it wherever you may need it. Sampling and writing to such texture cost 0.001ms of ur gpu time, which is pretty much a cheap hack.


    Example code:

    float4x4 mat1 = unity_WorldToShadow[0];
    float4x4 mat2 = unity_WorldToShadow[1];
    float4x4 mat3 = unity_WorldToShadow[2];
    float4x4 mat4 = unity_WorldToShadow[3];

    const float step = 1.0f / (4.0f * _Cascades);


    if (_Cascades == 1)
    {
    for (int c = 1; c <= 4; c++)
    if (i.uv.x < step*c)
    return mat1[c - 1];
    }
    else if (_Cascades == 2)
    {
    for (int h = 1; h <= 8;h++)
    if (i.uv.x < step*h) {
    if (h <= 4) return mat1[h - 1];
    else return mat2[h - 5];
    }
    }
    else if (_Cascades == 4)
    {
    for (int d = 1; d <= 16; d++)
    if (i.uv.x < step*d) {
    if (d <= 4) return mat1[d - 1];
    else if (d <= 8) return mat2[d - 5];
    else if (d <= 12) return mat3[d - 9];
    else return mat4[d - 13];
    }
    }

    return 0;
     
    DHein likes this.