Search Unity

Question Combine 2D Pixel Art Shadows

Discussion in 'Shaders' started by FuriousFury, Jan 9, 2023.

  1. FuriousFury

    FuriousFury

    Joined:
    Feb 22, 2016
    Posts:
    5
    We are developing an 2D Pixel Art RPG and using URP (2D Renderer). We have some "shadows" (sprites that act as shadows) in our scene. When multiple such objects overlap eachother they merge together (simple alpha blending), now we would like to combine shadows into one common shadows, such that shadows don't darken each other anymore.
    Do you guys have an idea how to achieve that?

    I was thinking about rendering everything below the shadows into a RenderTexture and the shadows into it's own RenderTexture (with full opaque) and then merge them together via shader/image effect. However I can't seem to find a good solution for that, since our Layers for culling are already in heavy usage and adding more is not really feasible (maybe adding one for the shadows themselves). Since Sorting Layers already define the order of rendering I essentially would like to "split" rendering of Sorting Layers into multiple RenderTexture/steps, how could I achieve that?

    Best,
    Kai

    upload_2023-1-9_12-30-35.png
     
    soroush-abasian likes this.
  2. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,513
    Your idea is a perfectly fine approach. I think it would take another camera though because the 2D Renderer doesn't let you remove a layer from rendering in the main pass. I had to fork it to make it play better with Renderer Features. But a second camera should work just fine. That camera targets your layer, outputs to a RT, and your main camera removes that layer, but displays the RT through some material.

    There's not a good way to hook stuff like this between Sorting Layers without forking the 2D renderer and that will probably be a pain, and potentially not possible b/c I'm not sure that you're allowed to change the camera color attachment during a pass, which is what this would call for.

    That
    suggestion, however, would be very useful but it's also not the direction Unity is headed because their philosophy is increasingly against this kind of flexibility; they want Render Graph and other improvements to optimize your passes behind the scenes and so your passes can't change mid-pass unpredictably (from the pipeline's vantage point).

    That said, there is a hacky way you could do this - without a 2nd cam - if you're not already using the _CameraSortingLayerTexture.

    (1) Render your shadows before everything else using a Solid Color on your camera that's black,
    (2) render your shadows red or something,
    (3) set the _CameraSortingLayerTexture to copy the frame's colors at this point,
    (4) now you have a black image with red blobs for shadows at full opacity so they merge together well,
    (5) render your ground/floor, sampling from the _CameraLayerSortingTexture and converting the red into a faded black with a lerp.
    (6) render trees and whatever.
     
  3. soroush-abasian

    soroush-abasian

    Joined:
    Jun 24, 2015
    Posts:
    6
    Hey guys you can use this shader for shadows and all shadows mixed together
    Just create a material with this shader and connect that material to your shadow sprite.
    Enjoy ;)
     

    Attached Files:

  4. soroush-abasian

    soroush-abasian

    Joined:
    Jun 24, 2015
    Posts:
    6