Search Unity

Merge shader

Discussion in 'Shaders' started by BigB, Aug 3, 2012.

  1. BigB

    BigB

    Joined:
    Oct 16, 2008
    Posts:
    672
    Hey guys,

    I'm sure you guys know how it looks in some rts games, when there's units selected ?
    Basically, there's one place with 1 circle below each unit selected, and when there's more than 1 unit selected, the circles merge clipping the inside of the circles, hard to explain.
    Take a look at this pics :)

    This one would be the image used in a selection plane :



    And this one, would be the result of 3 units selected near each other (the inside of the circles would be clipped) :



    This can also be seen in this shot, in the lower right corner, there's 2 units selected :



    Any ideas how to do this ?

    Thanks
     
  2. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Hmmm, my first idea would be to render the transparent inside of the rings first (before any of the blue rings), i.e. set the depth buffer in the inside (in fact you don't need blending, just use color masking to avoid rendering to the color buffer). Then render the blue rings slightly below such that the rings are not visible anywhere inside any of the rings.
     
    Last edited: Aug 4, 2012
  3. BigB

    BigB

    Joined:
    Oct 16, 2008
    Posts:
    672
    How would you go on doing that ? Writing to the depth buffer ?
     
  4. Jesus

    Jesus

    Joined:
    Jul 12, 2010
    Posts:
    502
    If you add then saturate the result you should be fine.
    (blue) + (white) = a
    (0,0,1) + (1,1,1) = (1,1,2)
    saturate (a) = b
    saturate (1,1,2) = (1,1,1)

    That's how you would do it for stuff in a shader.
     
  5. hausmaus

    hausmaus

    Joined:
    Dec 9, 2011
    Posts:
    105
    Here is a solution based on Martin Kraus's suggestion, which is spot-on:

    http://adrianswall.com/images/cg/simplealphamerge.zip

    Quick screenshot:


    This may be sloppy, but I just used two materials to force the correct draw order for the alpha/depth pass and the color pass, as it wasn't working with them as two passes in the same shader. There are some tricky details to get right in the shaders and the textures.

    So there are two shaders, one in Queue=Transparent, and the other in Transparent+1.

    The first shader does the interior circle alpha 0 and sets the depth, using "AlphaTest Less 0.5" to avoid setting alpha to 1.

    The second shader draws the alpha cutoff texture, respecting the existing 0 alpha where necessary. It also uses "Offset -0.001, 1" to force the depth conflict.

    It's also worth looking at the mask channels in the PSDs as the depth pass alpha channel needs to be fairly precise.

    Cheers,
    -abm
     
    Last edited: Aug 5, 2012
  6. cupsster

    cupsster

    Joined:
    Apr 14, 2009
    Posts:
    363
    Line renderer maybe?
     
  7. BigB

    BigB

    Joined:
    Oct 16, 2008
    Posts:
    672
    hausmaus, this is awesome, works pretty good, thank you very much !
    I got it working as I wanted, the only "problem" is that the planes need to be at the exact same Y for it to work, but it's just a matter of enforcing this in the selected units, not a big deal.

    Thanks again !
     
  8. hausmaus

    hausmaus

    Joined:
    Dec 9, 2011
    Posts:
    105
    Ah ok, well to solve that, try this:

    1) Copy and comment out the Offset line in the AlphaFX_Base shader

    2) Paste it into the AlphaFX_Alpha shader, and set the first term to a very large negative number, like
    Offset -100000, 1

    Seems to work here.

    Cheers,
    -abm
     
  9. Alesk

    Alesk

    Joined:
    Jul 15, 2010
    Posts:
    340
    Hi !

    Great solution :)
    Is it possible to get the same effect, but with a gradient fade around it ?
    I'm trying to do this kind of effect :

    $mask_with_holes.png

    By editing the textures, I've found how to get it work, but the holes borders are always sharp, even if I use a gradient texture.
    Any idea to share please ?

    Important precision : my game will run on iOS... (I still have to test the current solution on the final device to see if it works anyway)

    EDIT : just tested on iOS... and it doesn't works as expected.
    Instead of the circle, I get a square hole, so the texture is ignored :(

    Any idea on how I could get it to work on iOS ? (or any other solution wich could give me the same result ?)

    Thanks ^_^
     
    Last edited: Mar 6, 2013
  10. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Grillé... ;)
     
  11. Alesk

    Alesk

    Joined:
    Jul 15, 2010
    Posts:
    340
    Mouarf ^_^
    N'empêche que je suis sur une bonne piste là ;)
     
    Last edited: Jul 4, 2014
  12. Mr-Brent

    Mr-Brent

    Joined:
    Aug 20, 2013
    Posts:
    19
    I know this is a long dead thread, but I figured I'd post the answer regardless.

    For iOS, make sure you're using Open GL ES 2.0, and replace the AlphaTest lines in hausmaus's code with clip(-1) commands in the actual main.

    Code (csharp):
    1.  
    2. //in the alpha shader
    3.  
    4. half4 frag (v2f i) : COLOR
    5.             {
    6.                 half4 sample = tex2D( _AlphaTex, i.uv );
    7.                
    8.                 if (sample.a > .5) {
    9.                     clip(-1);
    10.                 }
    11.                
    12.                 return sample;
    13.             }
    14.  
     
  13. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    its definitely possible !

    I experimented a lot time (brute force ^^) with queue and i investigated that one pass should have Queue="Geometry+1" and merge shader to two pass and work fine

    there is code

    PHP:
    Shader "AE/Alpha FX Base"
    {
        
        
    Properties
        
    {
            
    _Color        ("Direct Color"Color) = (1.01.01.01.0)
            
    _MainTex    ("Main Diffuse (RGBA)"2D) = "" {}
            
    _AlphaTex    ("AlphaPad (RGBA)"2D)    = "" {}
        }
        
        
    SubShader
        
    {
            
            
            
                
    Tags
            
    {
                
    "Queue" "Geometry+1"
                "RenderType" 
    "Transparent"
                "IgnoreProjector" 
    "True"
            
    }
            
    Pass
            
    {
            
                
    Colormask A
                AlphaTest Less 0.5
                Offset 
    -10000001
                
                CGPROGRAM
                
    #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                
                
                
    uniform sampler2D _AlphaTex;
                
                
                
                
    struct v2f
                
    {
                    
    float4 pos SV_POSITION;
                    
    float2 uv  TEXCOORD0;
                };
                
                
                
                
    v2f vert (appdata_base v)
                {
                    
    v2f o;
                    
    o.pos mulUNITY_MATRIX_MVPv.vertex );
                    
    o.uv  v.texcoord.xy;
                    return 
    o;
                }
                
                
                
                
    half4 frag (v2f i) : COLOR
                
    {
                    
    half4 sample tex2D_AlphaTexi.uv );
                    
                    return 
    sample;
                }
                
                
                
                
    ENDCG
                
            
    }
            
                
    Tags
            
    {
                
    "Queue" "Transparent"
                "RenderType" 
    "Transparent"
                "IgnoreProjector" 
    "True"
            
    }
            
    Blend SrcAlpha OneMinusSrcAlpha
            Pass
            
    {        
            
                
    Colormask RGB
                Zwrite Off
                AlphaTest Greater 0.5
                
    //Offset -0.01, 1
                
                
                
    CGPROGRAM
                
    #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                
                
                
                
    uniform sampler2D _MainTex;
                
    half4 _Color;
                
                
                
                
    struct v2f
                
    {
                    
    float4 pos SV_POSITION;
                    
    float2 uv  TEXCOORD0;
                };
                
                
                
                
    v2f vert (appdata_base v)
                {
                    
    v2f o;
                    
    o.pos mulUNITY_MATRIX_MVPv.vertex );
                    
    o.uv  v.texcoord.xy;
                    return 
    o;
                }
                
                
                
                
    half4 frag (v2f i) : COLOR
                
    {
                    
    half4 sample tex2D_MainTexi.uv ) * _Color;
                    
                    return 
    sample;
                }
                
                
                
                
    ENDCG
                
            
    }
            
            
        }
        
        
    Fallback "VertexLit"
        
    }
    so i tried to convert it to projector shader (projector shader very easily map terrain shape) but fail


    there is code for projector

    PHP:
    Shader "AE/Alpha FX Base"
    {
        
        
    Properties
        
    {
            
    _Color        ("Direct Color"Color) = (1.01.01.01.0)
            
    _MainTex    ("Main Diffuse (RGBA)"2D) = "" {}
            
    _AlphaTex    ("AlphaPad (RGBA)"2D)    = "" {}
        }
        
        
    SubShader
        
    {
            
            
            
            
    Pass
            
    {
                
    Tags
            
    {
                
    "Queue" "Geometry+1"
                "RenderType" 
    "Transparent"
                "IgnoreProjector" 
    "True"
            
    }
            
                
    Colormask A
                AlphaTest Less 0.5
                Offset 
    -10000001
                
    //Zwrite Off
                
    CGPROGRAM
                
    #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                
                
                
    uniform sampler2D _AlphaTex;
                
    uniform float4x4 _Projector;
                
                
    struct vertexInput {
                
    float4 vertex POSITION;
                
    float3 normal NORMAL;
             };
                
                
    struct v2f
                
    {
                    
    float4 pos SV_POSITION;
                    
    float2 uv  TEXCOORD0;
                };
                
                
                
    v2f vert (vertexInput v)
                {
                    
    v2f o;
                    
    o.uv  mul(_Projector,v.vertex);
                    
    o.pos mulUNITY_MATRIX_MVPv.vertex );
                    
                    return 
    o;
                }
                
                
                
                
    half4 frag (v2f i) : COLOR
                
    {
                    
    half4 sample=tex2D_AlphaTexi.uv );
                    return 
    sample;
                }
                
                
                
                
    ENDCG
                
            
    }
            
            
            
            
            
    Pass
            
    {        
                    
    Tags
            
    {
                
    "Queue" "Transparent"
                "RenderType" 
    "Transparent"
                "IgnoreProjector" 
    "True"
            
    }
    Blend SrcAlpha OneMinusSrcAlpha    
                Colormask RGB
                Zwrite Off
                AlphaTest Greater 0.5
                
    //Offset -10000,1
                
                
                
    CGPROGRAM
                
    #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                
                
                
    uniform float4x4 _Projector;
                
    uniform sampler2D _MainTex;
                
    half4 _Color;
                
                
    struct vertexInput {
                
    float4 vertex POSITION;
                
    float3 normal NORMAL;
             };
                
                
    struct v2f
                
    {
                    
    float4 pos SV_POSITION;
                    
    float2 uv  TEXCOORD0;
                };
                
                
                
                
    v2f vert (vertexInput v)
                {
                    
    v2f o;
                    
    o.uv  mul(_Projector,v.vertex);
                    
    o.pos mulUNITY_MATRIX_MVPv.vertex );
                    
                    return 
    o;
                }
                
                
                
    half4 frag (v2f i) : COLOR
                
    {
                    
    half4 sample=tex2D_MainTexi.uv ) * _Color;
                    return 
    sample;
                }
                
                
                
                
    ENDCG
                
            
    }
            
            
        }
        
        
    Fallback "VertexLit"
        
    }

    and there is screenshot with projectors fail:

    $weird_projectors.JPG


    now, i haven't time so i hope u can fix this problem and share patch ;)

    Enjoy! ;)

    EDIT

    ok i deleted weird line by deleting mipmaps from main text but i cant solve problem with depth
     
    Last edited: Oct 16, 2013
  14. melong

    melong

    Joined:
    Sep 2, 2011
    Posts:
    22
    Hi,
    Sorry to revive this topic from the deads but i found this to be really useful for my actual project and i have a problem.
    While the shader works pretty well over mesh renderers when i tried to display my circles over an unity 2D Sprite i found that it wasn't working, as you can see in the screenshot below:

    It seems the Offset command is involved in this but i was not able to fix this as i never really understood how it works :)
    If someone has an idea about this that would be great.
     
  15. hausmaus

    hausmaus

    Joined:
    Dec 9, 2011
    Posts:
    105
    Hi Melong,

    Starting with the simplealphamerge.zip project I posted above, I added a Sprite (taken from http://opengameart.org/sites/defaul...ublic/lpc-art/professor_walk_cycle_no_hat.png although the texture shouldn't matter). In AE_AlphaFX_Base shader, I simply changed the offset line to Offset -1, -1, and that got the rings to appear over the sprites as expected.

    There are some great suggestions for improvements and changes to this shader in this thread, which I haven't had time to test, but you might try them next. Let us know how it works!

    Adrian
     
  16. Shinugami

    Shinugami

    Joined:
    Oct 17, 2012
    Posts:
    54
    Unity needs to do something to explain how to create such a useful UI element in game design. I've followed all the tutorials available by members whom are kind enough to spend the time and effort to create them however I have yet to find one that works. The closest one I found to what I want is this:
    http://forum.unity3d.com/threads/merge-sprites-by-color.172037/

    However I cannot use it because it produces a solid color around the sprite and I need the middle of the circles to be invisible. The outline looks fine but that's because the inner circle is being drawn over it. I actually need those inner parts to be 'merged' and thereby invisible while keeping the outline.

    I would even pay $50 for a working piece of code and yet there is NOTHING on the asset store.
     
  17. Medusa-Zenovka

    Medusa-Zenovka

    Joined:
    Oct 1, 2014
    Posts:
    29
    I was playing around with your code for hours. Its awesome, but I have no clue how to solve this problem. Does anyone have an idea?
     
  18. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    as i said remove mipmaps from circle texture thats all (if you want to fix lines, depth seems be impossible to fix)
     
  19. Medusa-Zenovka

    Medusa-Zenovka

    Joined:
    Oct 1, 2014
    Posts:
    29
    For the Mesh version: How do you enable rendering in DX11 mode?

    I figured that it has something to do with the depth calculation. If I change "Offset -1000000, 1" to "Offset 1000000, 1" for example, the first pass will not be drawn, instead the second pass is visible. How can I achieve the same result above in DX11?
     

    Attached Files:

  20. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    sorry im not familiar with dx11
     
  21. Medusa-Zenovka

    Medusa-Zenovka

    Joined:
    Oct 1, 2014
    Posts:
    29
    Me as well. But after playing around for a while, it seems that
    Code (Shader):
    1. clip(sample.a * -0.01);
    inside the first Pass's fragment function seems to make a good job, but not that well. The idea was cut the texture so the alpha is drawn and the rest simply gets discarded. The issue comes when planes overlap. It generates a sort of flickering like overlapping surfaces.


    EDIT:
    I managed to create a satisfying result based on your awesome work (Thx for that btw ;)):



    Code (DX11 Shader):
    1.  Shader "AE/Alpha FX Base DX11"
    2. {
    3.  
    4.     Properties
    5.     {
    6.         _Color        ("Direct Color", Color) = (1.0, 1.0, 1.0, 1.0)
    7.         _MainTex    ("Main Diffuse (RGBA)", 2D) = "" {}
    8.         _AlphaTex    ("AlphaPad (RGBA)", 2D)    = "" {}
    9.     }
    10.  
    11.     SubShader
    12.     {
    13.      
    14.      
    15.             Tags
    16.         {
    17.             "Queue" = "Geometry+1"
    18.             "RenderType" = "Transparent"
    19.             "IgnoreProjector" = "True"
    20.         }
    21.         Pass
    22.         {
    23.             Colormask RGBA
    24.             AlphaTest Less 0.5
    25. //            ZTest GEqual
    26.             Offset -100000, 1
    27.             Blend SrcAlpha OneMinusSrcAlpha
    28.  
    29.             CGPROGRAM
    30.             #pragma vertex vert
    31.             #pragma fragment frag
    32.             #include "UnityCG.cginc"
    33.          
    34.          
    35.             uniform sampler2D _AlphaTex;
    36.             half4 _Color;
    37.          
    38.          
    39.             struct v2f
    40.             {
    41.                 float4 pos : SV_POSITION;
    42.                 float2 uv  : TEXCOORD0;
    43.             };
    44.          
    45.          
    46.          
    47.             v2f vert (appdata_base v)
    48.             {
    49.                 v2f o;
    50.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
    51.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    52.                 o.uv  = v.texcoord.xy;
    53.                 return o;
    54.             }
    55.          
    56.          
    57.          
    58.             half4 frag (v2f i) : COLOR
    59.             {
    60.                 half4 sample = tex2D( _AlphaTex, i.uv );
    61.              
    62.                 //clip(sample.a * -0.01);
    63.                 if(sample.a > 0)
    64.                     discard;
    65.                 return sample;
    66.             }
    67.          
    68.          
    69.             ENDCG
    70.         }
    71.      
    72.             Tags
    73.         {
    74.             "Queue" = "Transparent"
    75.             "RenderType" = "Transparent"
    76.             "IgnoreProjector" = "True"
    77.         }
    78.         Pass
    79.         {    
    80.      
    81.             Colormask RGBA
    82.             Zwrite on
    83. //            ZTest LEqual
    84.             AlphaTest Greater 0.5
    85.                Blend SrcAlpha OneMinusSrcAlpha
    86.             //Offset -0.01, 1
    87.          
    88.          
    89.             CGPROGRAM
    90.             #pragma vertex vert
    91.             #pragma fragment frag
    92.             #include "UnityCG.cginc"
    93.          
    94.          
    95.          
    96.             uniform sampler2D _MainTex;
    97.             half4 _Color;
    98.          
    99.          
    100.          
    101.             struct v2f
    102.             {
    103.                 float4 pos : SV_POSITION;
    104.                 float2 uv  : TEXCOORD0;
    105.             };
    106.          
    107.          
    108.          
    109.             v2f vert (appdata_base v)
    110.             {
    111.                 v2f o;
    112.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
    113.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    114.                 o.uv  = v.texcoord.xy;
    115.                 return o;
    116.             }
    117.          
    118.          
    119.          
    120.             half4 frag (v2f i) : COLOR
    121.             {
    122.                 half4 sample = tex2D( _MainTex, i.uv ) * _Color;
    123.                 if(sample.a < 0.5)
    124.                     discard;
    125.                 return sample;
    126.             }
    127.          
    128.          
    129.          
    130.             ENDCG
    131.          
    132.         }
    133.      
    134.      
    135.     }
    136.  
    137.     Fallback "VertexLit"
    138.  
    139. }
     

    Attached Files:

    Last edited: Jul 25, 2015
  22. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hey! This is great, thanks! But I presume this won't fall back if the user doesn't have a DirectX 11 capable card? Or will it?
     
  23. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    if this is true what about using stencil buffer? if u have unity 5 you have all features for free. not sure if this will work for THIS effect though
     
  24. IliqNikushev

    IliqNikushev

    Joined:
    Feb 1, 2017
    Posts:
    22
  25. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    I hope the mods don't mind but I'm doing a major necro on this thread, I've been looking for a way to implement this for a mesh for years and it's been a struggle to find anything that isn't 2D, does anyone know how it would work? This is the closest effect I've been able to find to what I want. The other methods involving blur effects and so on are far too outdated.

    I had tried doing this ages ago by the way and of course this method is now obsolete.
     
    Last edited: Jul 16, 2021
    francisIsFine likes this.
  26. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
  27. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I don't mind at all. Seems relevant still.
     
  28. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    Then I'm also off to bump my black and white border thread because that shows up on the first page of search engines lol.
     
  29. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Only if it's relevant :p
     
    Lethn likes this.