Search Unity

2D shadows with custom depth texture - unhappy with my solution, is there a better approach?

Discussion in 'Shaders' started by Xarbrough, Jul 20, 2019.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Hi community,

    I need a little help with this system and I'm offering my existing solution in exchange. ;)

    The task to solve:
    • Simple 2D drop shadows for sprites which are only cast onto specific shadow receiving sprites
    • Decaying fog (sprites far away should be more white)
    I'm working on a 2D game with a perspective camera. All images are Unity SpriteRenderers. I want to cast simple drop shadows onto some of the sprites in the scene, no individual light sources requires, a global shadow/light angle is enough. The shadows should be cast by defining shadow casting meshes or lines and they should only show on specific sprites (e.g. not on the sky background, but on walls, etc.). Additionally, sprites further away from the camera should show fog which is colored by distance (special colors in the midground and then to white or black in the background).

    My current solution:
    • Use a second camera to render the scene a second time with a special culling mask and a shader to create a custom depth texture (because Unity only provides a depth texture for 3D meshes, but not sprites). The special DepthCamera copies the main cameras properties every frame and renders the scene via camera.RenderWithShader to write the depth values of almost all sprites (those that should receive shadows) into a RenderTexture (the depth map).
    • Shadow meshes sample the depth texture and draw a black semi-transparent overlay where the depth indicates that a shadow receiver is close (so the sky and other background elements are ignored).
    • The fog is applied to each sprite via its shader can optionally use the depth texture for special color effects depending on the depth distance.
    DepthCamera-Overview.PNG DepthCamera-Setup.PNG
    ShadowExample.PNG

    Things I want to achieve and have tried:
    • Shadows should be clipped at the border of shadow receivers, but the clipping should be soft and allow anti-aliasing or even transparency (which can be faked quite ok with the depth)
    • I have tried to use the Stencil Buffer to simply cut off the shadows on the edges of receiving sprites, but the stencil always has hard edges and looks quite pixelated. Setting up stencil IDs also is a little cumbersome for my level designers; I would prefer a solution that simply works after dropping sprites into the scene.
    • Instead of a second camera I have tried to use CommandBuffers to render the custom depth but it was tedious to have to maintain a list of renderers which are fed to the buffer and needs to be updated every frame and no builtin support for batching. Writing custom batching would be way beyond the scope of what I want for this effect.
    Problems with the current solution:
    • At runtime, render performance is greatly reduced, because the scene needs to be rendered two times, exactly doubling our frame time.
    • In the editor, performance is even worse, because I need additional cameras to render depth for the Game View, Scene View and potentially preview cameras, etc (although these are simply ignored currently).
    • The additional camera setup and handling of depth textures feels ugly, because it needs GameObjects with special setup and all shaders behave weirdly if the depth cameras are not rendering correctly in a scene (e.g. when testing other game systems in new scenes without the correct setup).
    • All in all, it seem that my current solution is a lot of work and setup and overhead for a small effect in-game.
    All in all, I'm not happy with my solution and I'm no graphics/shader programmer, so I don't have much experience to build on. Is there any better approach for this kind of effect? I'm not asking for a ready-made solution, but just the idea how to solve this problem without doubling render time in my 2D game. Thanks in advance!

    If anyone can use what I'm uploading here, feel free to use it in any way that you like! :)
     

    Attached Files:

    Last edited: Jul 20, 2019
    Fotal likes this.