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

Unity Inverted Mask Shader for 3D Objects

Discussion in 'Shaders' started by DJT4NN3R, Aug 22, 2018.

  1. DJT4NN3R

    DJT4NN3R

    Joined:
    Mar 25, 2014
    Posts:
    2
    Hi everyone. I'm looking for a way to blur objects as they pass into the camera's far clipping plane. I'm making a guitar hero-esque game, and I don't want my note objects to simply blink into existence with jagged edges as they pass through the clipping plane. I want to recreate the effect that they use in Guitar Hero at the far end of the note board, shown below:



    My first idea was to make some sort of fog effect material where the fog itself is invisible but still obscures objects, sort of like an inverse mask effect (example below).



    I then realized that:
    1) If an object that was once behind a particle with such a material then moved in front of that particle, it would have the same effect of popping in as it currently does. To remedy this, I would need to render thousands of tiny particles to make it less noticeable, which is inefficient.

    2) I have no idea where to even begin with such a thing.

    So I did some more searching and came across two Reddit posts asking for a shader that fades objects as they move away from the camera:
    - https://www.reddit.com/r/Unity3D/comments/7zjk3k/i_need_help_getting_this_soft_clipping_plane/
    - https://www.reddit.com/r/Unity3D/comments/22a3v9/soft_clipping_plane/

    The solution posted on the first post seemed to work well until i stretched the object along the z-axis. I then realized that it fades the entire object at once based on the object's center. This won't do, as the note board in my scene is thousands of units long.

    The second Reddit post I found sounded like what I was looking for, but when I tried to paste that shader into my project, it gave me an error stating:

    "Shader error in 'FadeDisFromCam': 'myvert': output parameter 'data' not completely initialized at line 29 (on d3d11)"

    Can anyone help me find a solution to what I need? To clarify, I'm not looking for a UI mask. I'm looking for a shader that I can use with materials on 3D objects and 2D sprites in the game world or something to achieve a similar effect.
     
    Last edited: Aug 22, 2018
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    I think you would have an easier time making a shader who's pixel output adjusts the pixel's alpha based on the clip-space position of the pixel. This would not be a mask, but a math operation you would do in your surface/fragment function.

    Something like this:
    Code (CSharp):
    1. // Convert clip-space y value to a value between 0 (top of screen) and 1 (bottom of screen)
    2. color.a = (1 - clipPos.y) / 2;
    3.  
    4. // Nudge every value down based on what percent of the screen you want the output fully invisible
    5. fixed percentScreenInvisible = 0.3;
    6. color.a -= percentScreenInvisible;
    7.  
    8. // Divide every value by the percent of the screen you want mid-fade
    9. fixed percentMidFade = 0.1;
    10. color.a /= percentMidFade;
    11.  
    12. // At this point, your alpha values may be negative or large. We want negative values invisible, and values over 1 to be fully visible, so simply clamping the values between 0 and 1 should finish the effect
    13. color.a = saturate(color.a);
    Hope this helps!