Search Unity

  1. How can our website serve you better? Give us your feedback. Take our survey and let us know.
    Dismiss Notice

No receive shadow in Fade mode.

Discussion in 'Shaders' started by Vit3D, Feb 3, 2020.

  1. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Hi all,
    Current Standard shader in Fade mode does not receive shadow.
    This did not happened if to use Cutout mode, but it does not fit my needs.
    Is there some way to fix this by editing shader code?
    Any suggestions will be very appreciated.
     
  2. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    9,765
    As far as I'm aware....

    This project from my signature deals with transparent objects receiving shadows:
    https://neginfinity.bitbucket.io/20...y.html#weighted-blended-transparency-in-unity
    https://github.com/NegInfinity/WeightedBlendedTransparency

    Long story short, as far as I know, It can't be done reliably. Or, at least couldn't be done reliable last time I tried it.

    • Directional shadows used by unity require z-buffer to be filled. So you can't have them on any transparent object. As in "not possible".
    • Unity does not pass shadowmaps to transparent objects. (unless something changed)
    The way used in the linked project is this:
    Code (csharp):
    1.  
    2. SubShader{
    3.      Tags{ "RenderType"="Opaque" "Queue"="AlphaTest+50"} //This a hack. A horrible horrible hack.
    4.  
    What does it do?

    Well, it lies to the shader system, and says that alpha-transparent object is actually an alpha-test one, except it manually ensures that it is rendered last by overriding queue. This causes engine to pass shadowmaps into the shader. This does work for point and spot light, however, because the shader is lying to the system, directional lights do not work... and outdoor scenes do not work either. Because the "transparent" object is erased by skybox.

    So. The best idea would be to actually use Cutout shader and fake transparency via dithering. Plenty of console titles seems to be doing that.
     
  3. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    5,670
    While I don't know how they did it, the korean unite shader talk by the creator of hongai impact 3 show transparent shadow on character... probably because it's a control scene ...
    upload_2020-2-3_13-1-5.png

    The talk is in english too
     
  4. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Many thanks for replies.

    @neginfinity

    I tested Your "AlphaTest+50" method, unfortunately it does not work in the last Unity version.
    Maybe I should explain - I tried to make Hair shader. Cutout mode is not suitable because it produce hard edges.

    But is it possible to blend Cutout pass and Transparency (Fade) pass in the single shader?
    Can I someway modify Standard shader to do this or I need to write completely custom shader?
     
  5. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    9,765
    You can have a shader that has both Cutout and Transparent subshaders, but I do not recommend it.

    Given that semi-transparent objects do not receive shadows, semi-transparent parts of hair will GLOW in shadowed areas. It will be horrible.

    Try to check out this asset and see if you can learn anything from it, though (assuming you get it to work):
    https://assetstore.unity.com/packages/essentials/the-blacksmith-hair-shader-39945
     
  6. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Many thanks neginfinity!

    I tested Blacksmith Hair Shader, unfortunately it does not receive shadows too.
    I already made Double Sided modification of Standard (Specular) shader and it works practically the same way in the Transparent (Fade) mode as this Blacksmith Hair Shader. Problems only is to force it to receive shadows.
    It's even strange that Unity development team still did not solve this old problem.
     
  7. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    9,765
    Like I said before, it is because of directional lights. Directional lights - with shadows, in unity - require filled zbuffer. And transparent objects do not fill zbuffer.

    Your best bet is to use cutout with dithered transparency. Those will receive shadows.
     
  8. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    5,670
  9. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Many thanks for suggestion and link to tutorial.

    I think that dithered transparency could be good alternative solution if there is no way to force receiving shadow in Fade mode.
    I found some dithered transparency shader examples, but all of them affect on whole object, not on existed transparency texture.

    I got idea to use something like Dissolve effect used in Photoshop for blending layers. Unfortunately I'm not strong enough in the shader codding to implement this in code directly (I specialized on character modeling). So currently I'm working at substance which will apply Dissolve effect on existed alpha channel.

    Hope that if to use Cutout mode with this dissolved alpha and add post processing anti-aliasing, the result will not very bad. Will test this with my existed hair model.
     
  10. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    9,765
    Well.

    Unity has surface shader examples here:
    https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html

    And quick google search lands me on this project:
    https://github.com/gkjohnson/unity-dithered-transparency-shader

    Shouldn't be hard to adapt this to texture alpha channel...
     
  11. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,607
    That's for baked lighting. Unity supports baked lighting & shadows on static objects. Real time shadows though ...

    There's a now 12 year old thread on this exact topic.
    https://forum.unity.com/threads/no-shadows-visible-on-transparency-shaders.9909/
    The answer hasn't changed. No, it's not possible for transparent objects to receive real time shadows in Unity.*

    * At least not all lights when using the built in renderers, and not without significant work.

    There's some hacks with hair where it's actually two shaders, as mentioned above. A cutout shader that does receive shadows, and a transparent shader that does not, or receives the same shadows as the objects behind it. Under certain lighting scenarios this works okay, but it's pretty nasty.

    If you only need shadows from the main directional light, there's a method here from @Gaxil that copies the shadow map reference to allow for for reuse later on transparent objects.
    https://github.com/Gaxil/Unity-InteriorMapping
    I link to the relevant files here:
    https://forum.unity.com/threads/no-shadows-visible-on-transparency-shaders.9909/page-3#post-4914971
    That requires fully customized shaders, but it does work.


    If you want to support other light types, the solution there is to completely replace Unity's lighting system and write a new one from scratch.

    No. Really.

    Valve did that for The Lab Renderer so it can support shadows on transparent objects, and released it publicly for free, but haven't updated it so it no longer works with modern versions of Unity.


    The LWRP & URP could techncially support shadows on transparent objects, but again Unity pulled that last I looked. Maybe it's back in and fixed for the recent versions of the URP, but it was very broken for a long time.


    That leaves the HDRP, which does support shadows from all light types on any surface, including transparent ones.
     
    Last edited: Feb 5, 2020
  12. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,607
    The way they did that was by rendering their own shadow maps. ie. they replaced Unity's lighting system with a custom one for characters. Basically each character renders out a custom high resolution shadow map limited to the view & character bounds to maximize it's quality. It sounds like they're then doing a hack for the transparent shadows by just assuming the shadow's intensity is based on the closest object's opacity... at least that's what I'm getting from the talk. But they might be using a single channel version of this instead and the translation just isn't coming across quite right.
    https://wickedengine.net/2018/01/18/easy-transparent-shadow-maps/

    The Blacksmith project used something similar, sans the transparent shadow support. It also doesn't work anymore on anything newer than like Unity 5.2.
    https://blogs.unity3d.com/2015/05/28/unique-character-shadows-in-the-blacksmith/
     
    neoshaman likes this.
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,607
    For Wayward Sky I added support for one layer of transparent objects receiving shadows by way of abusing an inferred rendering like approach.
    https://mynameismjp.wordpress.com/2010/01/10/inferred-rendering/

    I rendered objects as part of the opaque queue and dither them in the screen space camera depth texture. This is what actually receives the main directional light's shadows in Unity. Later objects sample from a screen space shadow texture. Catlike Coding has a whole tutorial on how the built in main directional shadows work.
    https://catlikecoding.com/unity/tutorials/rendering/part-7/

    Then, because the shadow receiver is dithered, instead of sampling the screen space shadow map using the screen position, I sample multiple points in the depth texture to find the one closest to the current fragment depth, and use the screen space shadows from that. I posted a proof of concept of that code here:
    https://forum.unity.com/threads/fixing-screen-space-directional-shadows-and-anti-aliasing.379902/

    Another aspect of this was those objects were using alpha to coverage for transparency so they sorted properly, which requires MSAA. The technique linked to above was created to fix shadows on MSAA edge, but the transparent shadows was a happy accident it also enabled.

    I don't do this anymore and just use the technique Gaxil used as it works on any arbitrary transparent surface. But the inferred rendering option is faster. I still use the MSAA fixup though for opaques.
     
    neoshaman likes this.
  14. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Hi all,

    @bgolus
    Many thanks for so detailed and very useful explanation!

    I created substance for alpha dissolving and compared visualization of my hair model in Cutout mode with and without alpha channel dissolving. Unfortunately this method is not fit to hair models alphas -- it just produces unpleasant pixel artifacts near borders. Although, I think, it could be useful for smooth alpha textures without small elements (gradients for example).

    So because Cutout mode is only possible solution in current Unity version for hair model if receiving shadow required, will be great to solve the problem with sharp borders. Is there some method to "smooth" borders for chosen game objects (with Cutout shader) without using Post Processing Anti-Aliasing?

    By the way, I finished modification of v2019.3 Standard Specular shader for Double Sided support and You can find it in attach to this post. There is nothing new or original in it -- I just add extra pass for back face visualization. So it is not "multipurpose" Double Sided shader, but just version oriented on hair visualization.
    If You decided to take a look at it, maybe You could advise how to make it better and/or fix my mistakes I possibly made.
     

    Attached Files:

    Last edited: Feb 5, 2020
  15. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,607
    It's sharp borders or no shadow receiving. Those are the only two options. There is no "in between" without the techniques I discussed above, or post processing. BTW, the dithered transparency approach is what most AAA games have used for the last decade or so, and they hide the artifacts of that with TAA or FXAA.
     
    neoshaman likes this.
unityunity