Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Resolved Shader for making objects in front of characters semi-transparent

Discussion in 'Shaders' started by florianp, Sep 7, 2021.

  1. florianp

    florianp

    Joined:
    Jun 16, 2013
    Posts:
    7
    I am working on a 2D hex-based isometric game and need to find a way to show the player/enemy characters when they are behind obstacles. For example, if the player is behind a tree, I would like for the part of the tree that the player is behind to be semi-transparent, so the player is visible.

    Is there any way to achieve this with shaders?
     
  2. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    Hi,
    On high level an easy solution would be to pass the character screen position to the shader and make it transparent where the player is.
     
  3. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    i.e. something like this. I just cooked up a quick and dirty proto. Screen position of the object is assigned to the shader graph (Just use SetVector and the correct parameter Reference name.) Then just perform some sort of distance calculation or however you want to decide what is transparent. Here I measured the distance between the Screen Position and the screen position of the player character. Then I just rendered a fade and used dithering + alpha clip for the simulated transparency.

    Something like this would probably do the trick?

    20210907_transparent_wall.PNG
     
    florianp likes this.
  4. florianp

    florianp

    Joined:
    Jun 16, 2013
    Posts:
    7
    Thank you for your suggestion! I will give this solution a try. I initially had something in mind along the lines of stencil buffers, but this should work as well.
     
  5. florianp

    florianp

    Joined:
    Jun 16, 2013
    Posts:
    7
    I implemented a variation of this approach, and calculating the transparency via distance between objects creates a fading circle around the player, which is not what I want. Ideally, the outline of transparency should be only around the player sprite.

    Comparing positions does not yield enough information in regards to the "shape" of the sprite (i.e. what parts of it are transparent and which are not). I'm thinking of modifying this approach and sampling the character texture with the character UVs, but inside the obstacles shader, converting the obstacle's UVs to the character's UVs, thus creating a mask, but I am not sure that this is even possible.
     
  6. florianp

    florianp

    Joined:
    Jun 16, 2013
    Posts:
    7
    I managed to find a solution to the problem. It involves using the stencil buffer and two passes for the obstacle shader.

    In the character shader, we always write a value to the stencil buffer (for example 2). In the obstacle shader, we write two passes, each with each own stencil check. In the first pass, the stencil check passes only if the value is not equal to the one in the character (i.e. there is no overlap). In this pass, we draw the sampled texture with full opacity. In the second pass, we make the stencil check so it passes only for pixels that were drawn from the character (equal to 2). Here, we sample the texture (like in the previous step), but we change the alpha so that the character is visible through it.
     

    Attached Files:

  7. darksire

    darksire

    Joined:
    Dec 16, 2013
    Posts:
    10
    can you share the Shaders please ?