Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Why can't Sprites gameobjects cast shadows?

Discussion in '2D' started by WrongTarget, Dec 6, 2013.

  1. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    Anyone have a clue?
     
  2. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    by nature sprites aren't going to cast shadows, because they aren't 3D. The only way to get sprites to cast shadows is to write your own special method for it, because its not something most developers use in 2D games, and instead they rely on artists who just "bake in" the shadows to the artwork...
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Sprites are 3D (they're similar to the quad primitive), but the SpriteRenderer component doesn't work with shadows. You can use a quad with a transparent/cutout shader instead.

    --Eric
     
    machengchn and unity_1830018 like this.
  4. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    In what way Eric5h5? Do you mean as in using them instead Unity Sprites at all?
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yes; SpriteRenderer is not used by shadows in Unity, so if you want shadows then as far as I know you can't use SpriteRenderer.

    --Eric
     
  6. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    Ok! Thanks. Here's to hoping that'll feature come in some future update.
     
  7. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    ooh right I should have clarified the 3d part better, listen to this guy lol
     
  8. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    Martin3371, eelstork and theANMATOR2b like this.
  9. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    TomasJ,

    I added a script enabling castShadows and receiveShadows to my Sprite gameobject and it still won't cast any shadow.
     
  10. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Will have to agree here.The following pictures show this with a Sprite Rock I tested. The characters in the picture are using a custom CutoutShader (https://www.assetstore.unity3d.com/#/content/5568) which is incompatible with the Sprite Render. It's there to show the desired behavior, but something I want to move away from, and just use sprites.

    Also the Sprite is lit just fine, using the supplied Sprite/Diffuse shader, but reverting this back to the default doesn't help with shadows.
    $SpriteShadow1.PNG
    $SpriteShadow2.PNG

    If it's hard to see, the shadow on the right is being cast by the little samurai, not the rock, indeed the samurai's shadow is going *through* the rock. The rock is neither recieving, nor projecting a shadow.
     
    Last edited: Dec 16, 2013
    lassade likes this.
  11. trevex

    trevex

    Joined:
    Apr 10, 2013
    Posts:
    17
    Shadows are not supported by the default sprite shaders. Setting castShadows/receiveShadows to true doesn't change that.

    You have several options though, dependent on the desired effect:
    1. Duplicate the default sprite diffuse shader and add the surface parameter "addshadows". To get cutout shadows you'll need to change the fallback and introduce the _Cutout material parameter as well.
    2. Simply use Quads straight away as @Eric5h5 stated (so using the MeshRenderer instead) and alpha cutout shaders.
    3. Use invisible shadow casters (although these might not necessarily interact well with you sprite animations) i.e. create you shadow meshes and use a shader only invoking the vertex lit's shadow collector and caster passes (this technique is helpful if you want "shadow shafts")
     
    theANMATOR2b likes this.
  12. trevex

    trevex

    Joined:
    Apr 10, 2013
    Posts:
    17
    Pic of options 1:
    $Screen Shot 2013-12-16 at 15.26.32.png
    And option 3 used for "shadow shafts":
    $Screen Shot 2013-12-16 at 15.22.09.png
     
  13. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Hey Trevex, thanks for the info!

    I'm a complete shader n00b - can you post that modified shader code for option 1, or let me know the syntax for adding the surface parameter, and introducing _Cutout material param - I can probably muddle through this, but if you have the code handy much appreciated :)

    3 looks like a cool option - did you use the 2d volumetric lighting plugin for that or is that something you rolled yourself? Your game looks cool! Been playing a lot of starbound lately, and while not for my current 2d project, at some point I want to take a look at doing something similar to their lighting system.
     
  14. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
  15. OceanBlue

    OceanBlue

    Joined:
    May 2, 2013
    Posts:
    251


    Hi

    I'm curious - how did you get the characters' shadows to project large like that? Your lighting is really nice and would love to know how you did this. I'm only learning now about lighting/shaders etc, and would really appreciate the advice.

    Also, anyone have any updates yet on projecting shadows from sprites with Unity 2d? I have the CutoutShader mentioned above, too, but as mentioned, it doesn't work. I'm currently using the sprite>diffuse, but no shadows
     
  16. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    You need to actually use the Lit3d cutout shader, if you're using the sprite -> diffuse it's not working - that's the reason why I posted :)

    Hopefully @trevex can drop a bit more mad shader knowledge up in here
     
  17. trevex

    trevex

    Joined:
    Apr 10, 2013
    Posts:
    17
    Since my shader involves a lot more than just the shadow part here is a short guide on how to enable shadow casting on sprites:

    1. Get the unity shader sources, duplicate the Sprite-diffuse.shader and rename it

    2. Add the addshadow parameter to the surface shader, i.e. Line 28 will look like this:
    #pragma surface surf Lambert alpha addshadow vertex:vert

    3. As previously mentioned castShadow needs to be set to true manually

    4. You should now be able to see shadows casted by your sprite, although they will be most likely squares.

    5. To solve this the shadow caster of the cutout shader needs to be used. This can be done by changing the fallback to it, i.e. Line 60 will look like this:
    Fallback "Transparent/Cutout/VertexLit"

    6. The cutout shader also needs the cutoff value, otherwise you'll still have just squares, so add it to your material uniforms, i.e. add this after Line 7:
    _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.5

    7. See your shadows in action!
     
    Arkade, Ormanus and theANMATOR2b like this.
  18. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Knowledge dropped! Going to check this out - will post results. Cheers!
     
  19. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    The shader I posted above has all these modifications you suggest, trevex, and it still doesn't work :S
    I tried doing it from scratch anyway, and no success.
     
  20. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    Please Jesse, let me know if you achieve anything.
     
  21. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
    Nevermind! Got it work. I wasn't enabling castshadow correctly, rookie mistake.
     
  22. OceanBlue

    OceanBlue

    Joined:
    May 2, 2013
    Posts:
    251
    Works perfectly thank you
     
  23. OceanBlue

    OceanBlue

    Joined:
    May 2, 2013
    Posts:
    251

    I have that cutout shader, but it doesn't work on sprites.
     
  24. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    It isn't meant to, I was saying that's what I had used in my picture.

    I've since changed to Trevex's method for my sprites.

    Edit - hmm I got the sprites to cast shadows - I can't seem to get recieve shadows working on the sprites however
     
    Last edited: Dec 19, 2013
  25. trialforce

    trialforce

    Joined:
    Apr 15, 2012
    Posts:
    22
    Thank you!

    The shader works for me but my shadow is hard (rough), I need soft shadows like yours;

    Look at the shadow of the box, smooth.

    Any suggestions?


    [IMAGE]79371[/IMAGE]
     

    Attached Files:

  26. Futch

    Futch

    Joined:
    Feb 27, 2013
    Posts:
    5
    Having a similar issue. I'd love to hear if the aforementioned solution worked for you guys before I went through the trouble myself.
     
  27. DigiScot

    DigiScot

    Joined:
    Aug 23, 2013
    Posts:
    27
    Any chance someone can explain how to get the default Sprite-Diffuse shader to edit as explained by trevex, or post the touched up shader... and how to use it thereafter.... I'm really new to shaders, they baffle me!

    oh and do you need Pro for this to work?
     
  28. WrongTarget

    WrongTarget

    Joined:
    Nov 18, 2013
    Posts:
    43
  29. kheldorin

    kheldorin

    Joined:
    May 28, 2015
    Posts:
    22
    Sorry for digging up an old thread but,

    I managed to get the sprites to cast shadows but they can't receive shadows. The only objects that are receiving shadows are the non-sprites. Is it possible to get the sprites to receive shadows?
     
  30. Zegux

    Zegux

    Joined:
    Jul 16, 2015
    Posts:
    1
    Go to the object which uses the Sprite Renderer. Over the inspector is a lock icon, click the button to the right of it. A menu will appear, select and click debug. Now if you look back at the Sprite Renderer, you should see options like m_CastShadows and m_RecieveShadows. Change them according to your needs.
     
    Bezoro and theANMATOR2b like this.
  31. vasyatko

    vasyatko

    Joined:
    Jan 21, 2015
    Posts:
    4
    It works only for CastShadows. Even if you attach a script
    GetComponent<Renderer>().receiveShadows = receiveShadow;
    GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;

    sprites do not cast shadows on the other sprites.
     
  32. tmkebr

    tmkebr

    Joined:
    Jun 14, 2015
    Posts:
    2
    There's no way around this?
     
  33. k-skills

    k-skills

    Joined:
    Jun 3, 2015
    Posts:
    2
    there is a way around this cause i got it to work...
    but im not sure how to explain.
     
  34. k-skills

    k-skills

    Joined:
    Jun 3, 2015
    Posts:
    2
    in debug mode i select the casting and recieving on my player gameobject.

    the material i used for my player gameobject was a new material with

    shader: standard
    rendering mode: cutout.
    mainmaps/albedo: player spritesheet (none works also)

    the material on my level mesh is the same as my player object!
    the only difference is the mainmap spritesheet.

    i hope this helps a little...
     

    Attached Files:

    Bezoro, Harinezumi and lukefrog like this.
  35. strinnikca

    strinnikca

    Joined:
    Feb 28, 2016
    Posts:
    1
    I have one question. With this way (using modified shader) object does not become true 3D object. If I rotate it 180 degrees and rays from light source go to its backside, there is no shadow. The same as with Quad.
    Is it possible to fix this issue somehow?
     
    Last edited: May 28, 2016
  36. Daedalus216

    Daedalus216

    Joined:
    Apr 11, 2017
    Posts:
    1
    It's a simple fix to get shadows from both directions. Now 'cast shadows' has a drop-bar allowing you to select 'two sided'. This along with everything k-skills said will accomplish the task
     
    Bezoro likes this.
  37. lvulcanis

    lvulcanis

    Joined:
    May 2, 2016
    Posts:
    6
    Thank you soo much! This help me a lot!!!
     
  38. OG_oliver

    OG_oliver

    Joined:
    Aug 11, 2019
    Posts:
    15
    I'm in the Universal Render Pipeline and I was able to make the sprites cast shadows but I can't make the receive shadows. I tried with the method above but no shadow is displayed over the sprites. My shader is the one WrongTarget made.
     
    Fotal likes this.
  39. Fotal

    Fotal

    Joined:
    Apr 9, 2019
    Posts:
    38
    Hi, tell please, how did you manage to make the sprites cast a shadow?
     
    OG_oliver likes this.
  40. OG_oliver

    OG_oliver

    Joined:
    Aug 11, 2019
    Posts:
    15
    To enable the shadows cast and received by sprites you just need to be in debug mode (first screenshot) and then, enable the 3 options I highlighted:
    - Dynamic Occludee
    - Receive shadows
    - Cast Shadows:
    important tip about this one: if you select "Two Sided", make sure your shader support both the front and the back of your sprites. Otherwise, if you are flipping your sprites at some point, one side won't work and even worst, it may even be invisible. If it works fine right away you can just ignore this.​
     

    Attached Files:

    TibiTibith and Fotal like this.
  41. Tiberius1701

    Tiberius1701

    Joined:
    Sep 16, 2014
    Posts:
    71
    @OG_oliver At least with Unity 2020.2.0f1 URP, the receive shadows flag has no effect. Screen_MedBarracks_Decal.jpg
     
  42. OG_oliver

    OG_oliver

    Joined:
    Aug 11, 2019
    Posts:
    15
    I did this a while ago but I remember that I also had to create a special material with the shader graph in order to have the textures working right. Moreover, depending on how you are generating the borders of your sprite (what seems to be some kind of glow at first glance) you may have to make it with the shader graph if you want it to be affected by 3D lights. Unity interprets sprites as some kind of UI element, that's why they are not affected by light right away.