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

Merge sprites by color

Discussion in 'Shaders' started by Partyson, Feb 26, 2013.

  1. Partyson

    Partyson

    Joined:
    Feb 26, 2013
    Posts:
    6
    I have a series of sprites all on the same z-axis. I'd like to be able to merge their central color and not have their outline overlap, and be able to set its central color and outline. Just like the example below:

    $shader_example.png

    I've figured out how to assign the colors, but am unsure how to merge the sprites images. I think I could set the z-depth or use a grabpass, but those are expensive on mobile devices, right?

    Any tips?
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Can you make the outlines and central parts separate sprites, and composite them as (in this case) four layers?
     
  3. MarigoldFleur

    MarigoldFleur

    Joined:
    May 12, 2012
    Posts:
    1,353
    It looks like you're trying to make a metaball shader. I'm not familiar with how it'd be implemented in ShaderLab though. I know that a long-time ago there used to be a screen-space ShaderLab tutorial for it though.
     
  4. Partyson

    Partyson

    Joined:
    Feb 26, 2013
    Posts:
    6
    That is definitely one solution, Daniel. Have a separate outline sprite sitting below the base sprite. That's a lot of overdraw though, and this feels like it can be done with a shader. And it's a good exercise for me to learn more about shaders.
     
  5. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    if all spirtes have the same zdepth ,I think a bit z offset -1,-1 of the central color will do your work
     
  6. Partyson

    Partyson

    Joined:
    Feb 26, 2013
    Posts:
    6
    Yes that's exactly what I'm thinking of! But I've pored over tons of shaders and forum posts and still cannot figure out how to manipulate the zdepth. Can you point me in the right direction?
     
  7. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I don't think you can change depth values from a fragment shader on mobile. The deferred renderers used by all the hardware would have a really hard time with that even if they could do it, and doubling your overdraw would definitely be a faster solution.
     
  8. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Despite performance,you can do that with two passes,one with z offset,one without,and do alpha test in the correcct pass,then blend them
     
  9. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Again, though: deferred GPU architectures mean that an extra layer of overdraw is preferable to alpha testing.
     
  10. Partyson

    Partyson

    Joined:
    Feb 26, 2013
    Posts:
    6
    Can anyone provide me a simple example of using a texture to set the z offset? It may very well be the wrong direction, but it's something I'm interested in seeing and testing.

    And thoughts on using a grab pass and manually blending each pixel?
     
  11. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Daniel means,the best solution on mobile is to instaciate two Objects, one above another,that will make your problem not a shader issue
     
  12. Partyson

    Partyson

    Joined:
    Feb 26, 2013
    Posts:
    6
    Ok then that will likely be my final solution. Thanks all for the discussion! But I'd love to see an example of using a texture to set a z-offset. I've been trying to figure that out for days and hate to leave a problem unfinished...
     
  13. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
  14. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    two passes,with the second one has a smaller scale and z offset -1,-1,
     
  15. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    even resovle the z_fight, From your picture,i have another question:How about the outline merge? you make it use postrender?2D Sprit is different with 3d model.And if you use mesh to make the circle,then use PostRender make the outline,I think you get it easier.
     
    Last edited: Mar 1, 2013
  16. Partyson

    Partyson

    Joined:
    Feb 26, 2013
    Posts:
    6
    Ah ha! I did not understand that you could not manipulate z-depth on a pixel-by-pixel basis. It's done for all the geometry in the pass. I've made a shader that does what I want. I still may use two sprites, but still wanted to try this and share. Thanks everyone for the hints!

    If anyone is interested:
    $shader_example2.png

    Code (csharp):
    1. Shader "Assign Colors Z"
    2. {
    3.     Properties
    4.     {
    5.         _ColorMain   ("Main Color", Color) = (0.5, 0.5, 0.5, 1.0)
    6.         _ColorBorder ("Border", Color) = (1.0, 1.0, 1.0, 1.0)
    7.         _MainTex     ("Texture to blend", 2D) = "" {}
    8.     }
    9.    
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue" = "Transparent"
    15.         }
    16.        
    17.        
    18.         // Pass 1 draws all the circles with alpha.  They will overlap.
    19.         Pass
    20.         {
    21.             Zwrite Off
    22.             Blend SrcAlpha OneMinusSrcAlpha
    23.  
    24.             CGPROGRAM
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.             #include "UnityCG.cginc"
    28.            
    29.             uniform sampler2D _MainTex;
    30.             half4 _ColorMain;
    31.             half4 _ColorBorder;
    32.            
    33.             struct v2f
    34.             {
    35.                 float4 pos : SV_POSITION;
    36.                 float2 uv  : TEXCOORD0;
    37.             };
    38.            
    39.            
    40.             v2f vert (appdata_base v)
    41.             {
    42.                 v2f o;
    43.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    44.                 o.uv  = v.texcoord.xy;
    45.                 return o;
    46.             }
    47.            
    48.            
    49.             // Convert black to the main color, and white to the border color.
    50.             half4 frag (v2f i) : COLOR
    51.             {
    52.                 // get the texture's color for this pixel
    53.                 half4 color = tex2D( _MainTex, i.uv );
    54.                
    55.                 // get how far apart the border and main color are
    56.                 half4 delta = _ColorBorder - _ColorMain;
    57.                
    58.                 // the final color is the percentage difference between the two.  more white = more border color.  less white = less border color.
    59.                 half4 main = _ColorMain + (color * delta);
    60.                
    61.                 // manually set the alpha
    62.                 main.a = color.a;
    63.                
    64.                 return main;
    65.             }
    66.            
    67.             ENDCG
    68.         }
    69.        
    70.        
    71.         // Pass 2 redraws just the inner circle and pulls it towards the camera.  White texture pixels become alpha.
    72.         Pass
    73.         {
    74.             Offset -1, -1
    75.            
    76.             Blend SrcAlpha OneMinusSrcAlpha
    77.            
    78.             // ditch any pixels with >50% alpha
    79.             AlphaTest Greater 0.5
    80.            
    81.             CGPROGRAM
    82.             #pragma vertex vert
    83.             #pragma fragment frag
    84.             #include "UnityCG.cginc"
    85.            
    86.             uniform sampler2D _MainTex;
    87.             half4 _ColorMain;
    88.             half4 _ColorBorder;
    89.            
    90.             struct v2f
    91.             {
    92.                 float4 pos : SV_POSITION;
    93.                 float2 uv  : TEXCOORD0;
    94.             };
    95.            
    96.             v2f vert (appdata_base v)
    97.             {
    98.                 v2f o;
    99.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    100.                 o.uv  = v.texcoord.xy;
    101.                 return o;
    102.             }
    103.            
    104.             half4 frag (v2f i) : COLOR
    105.             {
    106.                 // get the texture's color for this pixel
    107.                 half4 color = tex2D( _MainTex, i.uv );
    108.                
    109.                 // set the main color for everything drawn
    110.                 half4 main = _ColorMain;
    111.                
    112.                 // make white become transparent
    113.                 main.a = min(color.a, 1-color.r);
    114.                
    115.                 return main;
    116.             }
    117.            
    118.             ENDCG
    119.         }
    120.     }
    121. }
    122.  
     
    Bloody-Swamp likes this.
  17. K0ST4S

    K0ST4S

    Joined:
    Feb 2, 2017
    Posts:
    35
    Does it still work?