Search Unity

Overlay Blend Mode Shader

Discussion in 'Shaders' started by Lex, May 6, 2013.

  1. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Alright, I'm not very familiar with Shaders but I'll try to explain in details what I'm trying to achieve, why, and what I achieved so far.

    The background

    I use NGUI for my Game GUI and one great feature is that it keeps all images from your GUI on the same Atlas. This is good for saving both space and drawcalls I guess.

    Okay, when using NGUI I use this Unlit Transparent Colored Shader, which let me pick a color and multiply with my texture, this is great when I have a white sprite and want to change it's color.

    Here is the Shader Code (I hope there's no problem sharing it here as it's the base for my other shader):

    Code (csharp):
    1.  
    2. Shader "Unlit/Transparent Colored"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         LOD 100
    12.  
    13.         Tags
    14.         {
    15.             "Queue" = "Transparent"
    16.             "IgnoreProjector" = "True"
    17.             "RenderType" = "Transparent"
    18.         }
    19.        
    20.         Pass
    21.         {
    22.             Cull Off
    23.             Lighting Off
    24.             ZWrite Off
    25.             Fog { Mode Off }
    26.             Offset -1, -1
    27.             ColorMask RGB
    28.             AlphaTest Greater .01
    29.             Blend SrcAlpha OneMinusSrcAlpha
    30.             ColorMaterial AmbientAndDiffuse
    31.            
    32.             SetTexture [_MainTex]
    33.             {
    34.                 Combine Texture * Primary
    35.             }
    36.         }
    37.     }
    38. }
    39.  
    The goal

    What I want to achieve is to have a monochromatic GUI that can change color based on the color I pick. In other words, I want to achieve a effect similar to the Overlay Blend Mode on Photoshop.

    Quoted from: http://www.photoshopessentials.com/photo-editing/layer-blend-modes/overlay/

    Using Images to explain that would be that the gray button bellow would change its color as I picked blue(0, 0, 255) or red(192,43,43).

    $btncircle.png

    What's achieved so far?

    By changing the shader above (and I had no Idea what I was doing) I could achieve a similar effect, that works quite well. Just change the previous shader Pass so it looks like this:

    Code (csharp):
    1.  
    2.         Pass
    3.         {
    4.             Cull Off
    5.             Lighting Off
    6.             ZWrite Off
    7.             Fog { Mode Off }
    8.             Offset -1, -1
    9.             ColorMask RGB
    10.             AlphaTest Greater .01
    11.             Blend SrcAlpha OneMinusSrcAlpha
    12.             ColorMaterial AmbientAndDiffuse
    13.            
    14.             SetTexture [_MainTex]
    15.             {
    16.                 Combine Texture +- Primary, Texture * Primary
    17.             }
    18.            
    19.             SetTexture [_MainTex]
    20.             {
    21.                 Combine Texture +- previous, Texture * Primary
    22.             }
    23.         }
    24.  
    The problem

    This shader works pretty well when I have grayscale buttons, the 50% gray looks about the color I pick and the "shadows and lights" seem to adjust well to the selected color.

    But when I put a colored sprite with this shader... well... I excpected that by selecting the 50% gray as my pick color everything should remain unchanged compared to the original sprite, but that's not what happen. Check the results bellow:

    Original / 50% gray picked

    $btntwitterx.png

    Because of that weird effect I had separate all my grayscale and colored sprites into 2 atlases, which causes me a lot of trouble with rendring order.

    The Request

    Can anyone help me achieve what I want with the right code so I could use the same atlas for colored and grayscale sprites? I mean, because obviously my Pass is not doing the Overlay Blend Mode right, it's just something similar.

    The Thanks

    Thanks in advance, specially if you had patience to read this big post. I hope everything is well explained.
     
    Last edited: May 15, 2013
  2. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    I have found some more info about the Overlay Formula, as I quoted before it combines Multiply with Screen blend modes.

    Wikipedia: http://en.wikipedia.org/wiki/Blend_modes
    StackOverflow: http://stackoverflow.com/questions/5825149/overlay-blend-mode-formula

    It seems I'll need an IF statement based on the texture pixel color... is there a code to check that in the SetTexture of a shader so I could chose between Screen and Multiply?

    Also, how can I use Screen Blend Mode? Multiply seems to be as easy as
    Code (csharp):
    1. Combine Texture * Primary
     
  3. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    If I understand correctly, you want what is described in this thread.

    Here are all those bits of code put together:

    Code (csharp):
    1. Shader "Custom/OverlayBlend"
    2. {
    3.     Properties {
    4.         _MainTex ("Texture", 2D) = "" {}
    5.         _Color ("Blend Color", Color) = (0.2, 0.3, 1 ,1)
    6.     }
    7.  
    8.     SubShader {
    9.  
    10.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    11.        
    12.         Lighting Off
    13.         Blend SrcAlpha OneMinusSrcAlpha
    14.         ZWrite Off
    15.         Fog { Mode Off }
    16.        
    17.         Pass {  
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #pragma fragmentoption ARB_precision_hint_fastest
    22.  
    23.             #include "UnityCG.cginc"
    24.  
    25.             struct appdata_t {
    26.                 float4 vertex : POSITION;
    27.                 fixed4 color : COLOR;
    28.                 float2 texcoord : TEXCOORD0;
    29.             };
    30.  
    31.             struct v2f {
    32.                 float4 vertex : POSITION;
    33.                 fixed4 color : COLOR;
    34.                 float2 texcoord : TEXCOORD0;
    35.             };
    36.  
    37.             sampler2D _MainTex;
    38.  
    39.             uniform float4 _MainTex_ST;
    40.             uniform float4 _Color;
    41.            
    42.             v2f vert (appdata_t v)
    43.             {
    44.                 v2f o;
    45.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    46.                 o.color = v.color;
    47.                 o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
    48.                 return o;
    49.             }
    50.  
    51.             fixed4 frag (v2f i) : COLOR
    52.             {
    53.                 // Get the raw texture value
    54.                 float4 texColor = tex2D(_MainTex, i.texcoord);
    55.                 // Calculate the twiceLuminance of the texture color
    56.                 float twiceLuminance =  dot(texColor, fixed4(0.2126, 0.7152, 0.0722, 0)) * 2;
    57.                 // Declare the output structure
    58.                
    59.                 fixed4 output = 0;
    60.                
    61.                 // The actual Overlay/High Light method is based on the shader
    62.                 if (twiceLuminance < 1) {
    63.                     output = lerp(fixed4(0, 0, 0, 0), _Color, twiceLuminance);
    64.                 } else {
    65.                     output = lerp(_Color, fixed4(1, 1, 1, 1), twiceLuminance - 1);
    66.                 }
    67.                
    68.                 // The alpha can actually just be a simple blend of the two-
    69.                 // makes things nicely controllable in both texture and color
    70.                 output.a  = texColor.a * _Color.a;
    71.                 return output;
    72.             }
    73.             ENDCG
    74.         }
    75.     }  
    76.  
    77.     Fallback off
    78. }
     
    kyungjin82 and sandolkakos like this.
  4. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    No Daniel, it didn't work, I guess the problem described in that thread is not exactly the same as what I want here. I'm still trying to find the right shader, maybe I'll have to use some CG code for that, right?
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    You'll definitely have to use Cg. Perhaps you can explain in more detail what you would like your possible inputs to be, and what output you expect in each case? I can't view any of your original attachments except the twitter logo.
     
  6. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Sorry for that, I updated the post with new images so I hope it works now.

    In adition now that I studied NGUI a little more I discovered what its color pick does, it does pixel coloring on the plane where the sprite is going to be rendered with the selected color. So basically the code I want is:

    Code (csharp):
    1. foreach texture pixel
    2. {
    3.   if (texture.pixel is darker than 0.5)
    4.   {
    5.     finalPixelColor = baseColor MULTIPLY texture.pixel.color
    6.   }
    7.   else
    8.   {
    9.     finalPixelColor = baseColor SCREEN texture.pixel.color
    10.   }
    11. }
    Sorry, I'm not familiar with CG script...
     
  7. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Still looking for a solution without success, can someone take a look on this or give me directions on what to study?
     
  8. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Up we go, still need some help here.
     
  9. HenryStrattonFW

    HenryStrattonFW

    Joined:
    Jul 27, 2012
    Posts:
    18
    Had a need for overlay a while back. However i made the mistake of trying to do the overlay on each channel RGB separately, didn't think to use luminescence for it. Anyway with that in mind, made a few changes to it and came up with something that seems to work. However not tested on any mobile device, I've read that using if tests on shaders isn't the best idea, and there may well be better ways to approximate the effect with less cost.

    Either way, here's what i came up with for it.

    Note: Not really knowing about luminescence at all not sure what the best value is for checking it. I found checking it < 1 looked a little bit off, checking <0 might also be useful (but without opening photoshop i cant compare the effect exactly) but 0.5 seems to give a decent effect as far as my memory of what an overlay does. However you may want to modify the value you check luminescence against if you want to fine tune.

    Code (csharp):
    1. Shader "Custom/OverlayBlend"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "" {}
    6.         _Color ("Blend Color", Color) = (0.5, 0.5, 0.5, 1.0)
    7.     }  
    8.  
    9.     SubShader
    10.     {
    11.         Tags
    12.         {
    13.             "Queue" = "Transparent"
    14.             "RenderType" = "Transparent"
    15.         }        
    16.  
    17.         Lighting Off
    18.         Blend SrcAlpha OneMinusSrcAlpha
    19.              
    20.         Pass
    21.         {  
    22.             CGPROGRAM
    23.             #pragma vertex vert
    24.             #pragma fragment frag
    25.             #pragma fragmentoption ARB_precision_hint_fastest
    26.  
    27.             #include "UnityCG.cginc"
    28.  
    29.             struct appdata_custom
    30.             {
    31.                 float4 vertex : POSITION;
    32.                 fixed2 uv : TEXCOORD0;
    33.             };
    34.  
    35.             struct v2f
    36.             {
    37.                 float4 vertex : POSITION;
    38.                 fixed2 uv : TEXCOORD0;
    39.             };
    40.            
    41.             sampler2D _MainTex;
    42.             fixed4 _MainTex_ST;
    43.             fixed4 _Color;            
    44.  
    45.             v2f vert (appdata_custom v)
    46.             {
    47.                 v2f o;
    48.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    49.                 o.uv = TRANSFORM_TEX(v.uv,_MainTex);
    50.                 return o;
    51.             }          
    52.  
    53.             fixed4 frag (v2f i) : COLOR
    54.             {
    55.                 fixed4 diffuse = tex2D(_MainTex, i.uv);
    56.                 fixed luminance =  dot(diffuse, fixed4(0.2126, 0.7152, 0.0722, 0));
    57.                 fixed oldAlpha = diffuse.a;
    58.  
    59.                 if (luminance < 0.5)
    60.                     diffuse *= 2 * _Color;
    61.                 else
    62.                     diffuse = 1-2*(1-diffuse)*(1-_Color);
    63.  
    64.                 diffuse.a  = oldAlpha * _Color.a;
    65.                 return diffuse;
    66.             }
    67.             ENDCG
    68.         }
    69.     }  
    70.     Fallback off
    71. }
     
    Last edited: Jun 5, 2013
  10. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Thanks a lot, this shader is almost what I need, I just need to know 2 things:

    1. Could you tell if it is going to run on mobile devices? If yes is it optimized enough for that?

    2. How can I use the mesh vertex color instead of the variable _Color of the shader?
     
  11. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Okay, with very few modifications I got it to work exactly like I wanted. Very special thanks to HenryStrattonFW.

    Code (csharp):
    1. Shader "Custom/OverlayBlend"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "" {}
    6.     }
    7.    
    8.     SubShader
    9.     {
    10.         Tags
    11.         {
    12.             "Queue" = "Transparent"
    13.             "RenderType" = "Transparent"
    14.         }
    15.        
    16.         Lighting Off
    17.         Blend SrcAlpha OneMinusSrcAlpha
    18.        
    19.         Pass
    20.         {
    21.             CGPROGRAM
    22.             #pragma vertex vert
    23.             #pragma fragment frag
    24.             #pragma fragmentoption ARB_precision_hint_fastest
    25.            
    26.             #include "UnityCG.cginc"
    27.            
    28.             struct appdata_custom
    29.             {
    30.                 float4 vertex : POSITION;
    31.                 fixed2 uv : TEXCOORD0;
    32.                 float4 color : COLOR;
    33.             };
    34.            
    35.             struct v2f
    36.             {
    37.                 float4 vertex : POSITION;
    38.                 fixed2 uv : TEXCOORD0;
    39.                 float4 color : COLOR;
    40.             };
    41.            
    42.             sampler2D _MainTex;
    43.             fixed4 _MainTex_ST;
    44.            
    45.             v2f vert (appdata_custom v)
    46.             {
    47.                 v2f o;
    48.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    49.                 o.uv = TRANSFORM_TEX(v.uv,_MainTex);
    50.                 o.color = v.color;
    51.                 return o;
    52.             }          
    53.            
    54.             fixed4 frag (v2f i) : COLOR
    55.             {
    56.                 fixed4 diffuse = tex2D(_MainTex, i.uv);
    57.                 fixed luminance =  dot(diffuse, fixed4(0.2126, 0.7152, 0.0722, 0));
    58.                 fixed oldAlpha = diffuse.a;
    59.                
    60.                 if (luminance < 0.5)
    61.                     diffuse *= 2 * i.color;
    62.                 else
    63.                     diffuse = 1-2*(1-diffuse)*(1-i.color);
    64.                
    65.                 diffuse.a  = oldAlpha * i.color.a;
    66.                 return diffuse;
    67.             }
    68.             ENDCG
    69.         }
    70.     }
    71.     Fallback off
    72. }
     
  12. Ball-E

    Ball-E

    Joined:
    Aug 30, 2013
    Posts:
    1
    Hi. I've just had to implement a overlay shader my self and came across this thread when I was looking for inspiration. Cool you got what you wanted Lax! But even though you aren't looking any more I think I'll post my solution as it might be helpful for others trying to do the same.

    My shader is more like the overlay mode in photoshop as it operates on the whole screen area. The algorithm is a direct implementation of the algorithm described on the wikipedia page you linked to in an earlier post. (http://en.wikipedia.org/wiki/Blend_modes#Overlay)

    Anyway here goes (some explanation can be found after the code):

    Code (csharp):
    1. Shader "Custom/Overlay" {
    2.     Properties {
    3.         _OverlayTex ("Overlay (RGB)", 2D) = "white" {}
    4.     }
    5.    
    6.     SubShader {
    7.         Tags { "RenderType"="Transparent" "Queue"="Transparent+1000"}
    8.         LOD 200
    9.        
    10.         GrabPass {}
    11.        
    12.         Pass {
    13.             CGPROGRAM
    14.            
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.            
    18.             #include "UnityCG.cginc"
    19.            
    20.             sampler2D _GrabTexture;
    21.             sampler2D _OverlayTex;
    22.            
    23.             struct appdata_t {
    24.                 float4 vertex : POSITION;
    25.                 float4 texcoord : TEXCOORD0;
    26.             };
    27.            
    28.             struct v2f {
    29.                 float4 vertex : POSITION;
    30.                 float2 uv : TEXCOORD0;
    31.                 float4 projPos : TEXCOORD1;
    32.             };
    33.            
    34.             float4 _OverlayTex_ST;
    35.            
    36.             v2f vert( appdata_t v ){
    37.                 v2f o;
    38.                 o.vertex = mul( UNITY_MATRIX_MVP, v.vertex );
    39.                 o.uv = TRANSFORM_TEX( v.texcoord, _OverlayTex );
    40.                 o.projPos = ComputeScreenPos( o.vertex );
    41.                 return o;
    42.             }
    43.            
    44.             half4 frag( v2f i ) : COLOR {
    45.                 i.projPos /= i.projPos.w;
    46.                 half4 base = tex2D( _GrabTexture, float2( i.projPos.xy ));
    47.                 half4 overlay = tex2D( _OverlayTex, i.uv );
    48.  
    49.                 return lerp(   1 - 2 * (1 - base) * (1 - overlay),    2 * base * overlay,    step( base, 0.5 ));
    50.             }
    51.            
    52.             ENDCG
    53.         }
    54.     }
    55. }
    As it can be seen above I use a pass to grab what is currently on the screen before rendering the overlay. This is a feature provided by Unity simply by including the GrabPass { } and it stores a reference to the grabbed texture in _GrabTexture. I can now use this as my base layer for the blend and I use normalized screen coordinates as uv's when reading from it (that is what the "o.projPos = ComputeScreenPos( o.vertex ); " and "i.projPos /= i.projPos.w;" lines are for). Finally I combine the two texture colors basted on the algorithm from the wikipedia page. The lerp and step functions is just another way of doing an if statement, This is hopefully less cost expensive than an actual if ( I'm by no means a shader expert! )

    I've also made a shorter version implemented as a surface shader. But it is probably not that useful since it reacts to lighting. (In my experience the color of the pixel is alway change at least a little when using surface shaders. Even though you define your own lighting model that ignores light! )

    Anyway, that's it. Hope somebody finds this help full.

    Cheers
    - Jakob
     
    KaterynaKuznetsova likes this.
  13. runonthespot

    runonthespot

    Joined:
    Sep 29, 2010
    Posts:
    305
    Yeah Jakob , liking the magic of your implementation of the overlay logic in a simple lerp...

    Wish I could find similar implementations of this set: http://forum.unity3d.com/threads/121661-Free-Photoshop-Blends - or some idea how you go from those if statements to what you produced.

    Either way, thanks for sharing!
     
  14. potte

    potte

    Joined:
    Jan 27, 2013
    Posts:
    6
    I used a plane and put it between the camera and the scene with this shader. the color looks right but it renders the scene upside down:confused:
    edit:
    nvm, my screen coordinate in unity is reversed that's why the output is upside down.
     
    Last edited: Sep 19, 2013
  15. Lex

    Lex

    Joined:
    Dec 2, 2009
    Posts:
    43
    Whoa, nice to see this post is still going on. I'll check that implementation later on on my project as it seems to be a bit more efficient.
     
  16. HenryStrattonFW

    HenryStrattonFW

    Joined:
    Jul 27, 2012
    Posts:
    18
    Been a long time since I saw this thread, nice to see some alternative suggestions. @Ball-E 's use a lerp and steps is a good way around the if test. Will have to remember that next time I need to dig up my old overlay shader.
     
  17. Spiral12

    Spiral12

    Joined:
    Jun 6, 2013
    Posts:
    5
    Hi,
    With unity5 the original shader in this thread is no longer usable.

    I tried this from Lex
    But I need the extra saturation from the original shader.

    this is the original shader:
    Code (CSharp):
    1.  
    2. Shader "Unlit/Transparent Colored"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         LOD 100
    12.         Tags
    13.         {
    14.             "Queue" = "Transparent"
    15.             "IgnoreProjector" = "True"
    16.             "RenderType" = "Transparent"
    17.         }
    18.      
    19.         Pass
    20.         {
    21.             Cull Off
    22.             Lighting Off
    23.             ZWrite Off
    24.             Fog { Mode Off }
    25.             Offset -1, -1
    26.             ColorMask RGB
    27.             AlphaTest Greater .01
    28.             Blend SrcAlpha OneMinusSrcAlpha
    29.             ColorMaterial AmbientAndDiffuse
    30.          
    31.             SetTexture [_MainTex]
    32.             {
    33.                 Combine Texture +- Primary, Texture * Primary
    34.             }
    35.          
    36.             SetTexture [_MainTex]
    37.             {
    38.                 Combine Texture +- previous, Texture * Primary
    39.             }
    40.         }
    41.     }
    42. }
    43.  
    How can I achieve the same effect in unity5?

    Thank you
     
  18. animgram

    animgram

    Joined:
    Nov 24, 2012
    Posts:
    2
    So, as Spiral12 correctly stated, almost none of this works with unity 5 anymore.

    Ball-E's last offer was the closest thing I got to a working shader, and after minor adjustments I got it to work in a GUI context.
    The transparent shaders in the custom overlay image were still rendered and affecting the image, though.

    The shader has therefore been modified to take transparency into account so custom images are correctly blended in, as well as introduced a property which allows you to modify the strength of the overall layer.

    The last thing missing (to follow the photoshop effect) would be to make sure that overlays with a light intensity of 0.5 are rendered transparent, right now it just defaults to screen.


    Code (CSharp):
    1. Shader "Custom/Overlay" {
    2.     Properties{
    3.         _MainTex("Texture", 2D) = "" {}
    4.         _str("Overlay Strength", Float) = 0.45
    5.     }
    6.  
    7.     SubShader{
    8.         Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
    9.  
    10.         GrabPass{}
    11.  
    12.         Pass{
    13.             CGPROGRAM
    14.  
    15. #pragma vertex vert
    16. #pragma fragment frag
    17.  
    18. #include "UnityCG.cginc"
    19.  
    20.             sampler2D _GrabTexture;
    21.             sampler2D _MainTex;
    22.             float _str;
    23.  
    24.             struct appdata_t {
    25.                 float4 vertex : POSITION;
    26.                 float4 texcoord : TEXCOORD0;
    27.             };
    28.  
    29.             struct v2f {
    30.                 float4 vertex : POSITION;
    31.                 float2 uv : TEXCOORD0;
    32.                 float4 projPos : TEXCOORD1;
    33.             };
    34.  
    35.             float4 _MainTex_ST;
    36.  
    37.             v2f vert(appdata_t v) {
    38.                 v2f o;
    39.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    40.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    41.                 o.projPos = ComputeScreenPos(o.vertex);
    42.                 return o;
    43.             }
    44.  
    45.             half4 frag(v2f i) : COLOR{
    46.                 i.projPos /= i.projPos.w;
    47.                 half4 base = tex2D(_GrabTexture, float2(i.projPos.x, 1-i.projPos.y));
    48.                 half gray = (base.r + base.g + base.b) / 3;
    49.                 half4 overlay = tex2D(_MainTex, i.uv);
    50.  
    51.                 float4 effect = lerp(1 - (2 * (1 - base)) * (1 - overlay), (2 * base) * overlay, step(gray, 0.5f));
    52.              
    53.                 return lerp(base, effect, (overlay.w * _str));
    54.             }
    55.  
    56.             ENDCG
    57.         }
    58.     }
    59. }
     
    Last edited: Aug 25, 2016
  19. FoxQ

    FoxQ

    Joined:
    Jan 13, 2014
    Posts:
    1
    I made a little change at line 51.

    step(gray, 0.5f) -> step(base, 0.5f)

    No idea what I've done but it looks exactly same as PS.

    Code (CSharp):
    1. Shader "Custom/Overlay" {
    2.     Properties{
    3.         _MainTex("Texture", 2D) = "" {}
    4.         _str("Overlay Strength", Float) = 0.45
    5.     }
    6.  
    7.     SubShader{
    8.         Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
    9.  
    10.         GrabPass{}
    11.  
    12.         Pass{
    13.             CGPROGRAM
    14.  
    15. #pragma vertex vert
    16. #pragma fragment frag
    17.  
    18. #include "UnityCG.cginc"
    19.  
    20.             sampler2D _GrabTexture;
    21.             sampler2D _MainTex;
    22.             float _str;
    23.  
    24.             struct appdata_t {
    25.                 float4 vertex : POSITION;
    26.                 float4 texcoord : TEXCOORD0;
    27.             };
    28.  
    29.             struct v2f {
    30.                 float4 vertex : POSITION;
    31.                 float2 uv : TEXCOORD0;
    32.                 float4 projPos : TEXCOORD1;
    33.             };
    34.  
    35.             float4 _MainTex_ST;
    36.  
    37.             v2f vert(appdata_t v) {
    38.                 v2f o;
    39.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    40.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    41.                 o.projPos = ComputeScreenPos(o.vertex);
    42.                 return o;
    43.             }
    44.  
    45.             half4 frag(v2f i) : COLOR{
    46.                 i.projPos /= i.projPos.w;
    47.                 half4 base = tex2D(_GrabTexture, float2(i.projPos.x, 1-i.projPos.y));
    48.                 half gray = (base.r + base.g + base.b) / 3;
    49.                 half4 overlay = tex2D(_MainTex, i.uv);
    50.  
    51.                 float4 effect = lerp(1 - (2 * (1 - base)) * (1 - overlay), (2 * base) * overlay, step(base, 0.5f));
    52.            
    53.                 return lerp(base, effect, (overlay.w * _str));
    54.             }
    55.  
    56.             ENDCG
    57.         }
    58.     }
    59. }
     
  20. olopez1

    olopez1

    Joined:
    Sep 13, 2012
    Posts:
    5
    It must be a noob question, but I have the same issue about it rendering upside down, how do you reversed the coordinates in the shader? If I play the scene on PC it renders the right way, but on mobile (and in the "Scene View") it renders upside down. I know it is because de coordinates are handled different between platforms, but like I've said I'm a shader noob, I down't know how make it render correctly in different platforms.
     
  21. animgram

    animgram

    Joined:
    Nov 24, 2012
    Posts:
    2
    Okay @FoxQ, I don't know why you would do that. I use gray so that the overall light level of the 3 color channels is used. I do not know if unity automatically assumes this with your method. I am specifically worried about your method also accounting for transparency, which I do not want in my case.

    And you are right @olopez1 sorry for taking so long, I've had the solution lying around for some time.

    The problem is indeed platform specific, and you rectify this by replacing line 47 with the following:

    #if SHADER_API_METAL || SHADER_API_D3D11
    half4 base = tex2D(_GrabTexture, float2(i.projPos.x, 1-i.projPos.y));
    #else
    half4 base = tex2D(_GrabTexture, float2(i.projPos.x, i.projPos.y));
    #endif


    This will make the shader mess up in the scene-view and hopefully nowhere else.
     
  22. davidguaita

    davidguaita

    Joined:
    Apr 20, 2013
    Posts:
    6
    Hi guys!

    Edit:

    I made a more simplified version, but by now it only works in the editor
    Basically, what I'm doing is just a substraction and an addition:

    half4 base = tex2D(_GrabTexture, float2(i.projPos.x, 1 - i.projPos.y));
    half4 overlay = tex2D(_MainTex, i.uv);
    half4 mixer = half4 (0.5, 0.5, 0.5, 0.5);

    return base+overlay-mixer;


    Here is all the code.

    Regards


    Code (CSharp):
    1. Shader "Custom/Overlay" {
    2.     Properties{
    3.         _MainTex("Texture", 2D) = "" {}
    4.  
    5.     }
    6.  
    7.         SubShader{
    8.         Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
    9.  
    10.         GrabPass{}
    11.  
    12.         Pass{
    13.         CGPROGRAM
    14.  
    15. #pragma vertex vert
    16. #pragma fragment frag
    17.  
    18. #include "UnityCG.cginc"
    19.  
    20.         sampler2D _GrabTexture;
    21.     sampler2D _MainTex;
    22.  
    23.  
    24.     struct appdata_t {
    25.         float4 vertex : POSITION;
    26.         float4 texcoord : TEXCOORD0;
    27.     };
    28.  
    29.     struct v2f {
    30.         float4 vertex : POSITION;
    31.         float2 uv : TEXCOORD0;
    32.         float4 projPos : TEXCOORD1;
    33.     };
    34.  
    35.     float4 _MainTex_ST;
    36.  
    37.     v2f vert(appdata_t v) {
    38.         v2f o;
    39.         o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    40.         o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    41.         o.projPos = ComputeScreenPos(o.vertex);
    42.         return o;
    43.     }
    44.  
    45.     half4 frag(v2f i) : COLOR{
    46.         i.projPos /= i.projPos.w;
    47.     half4 base = tex2D(_GrabTexture, float2(i.projPos.x, 1 - i.projPos.y));
    48.  
    49.     half4 overlay = tex2D(_MainTex, i.uv);
    50.     half4 mixer = half4 (0.5, 0.5, 0.5, 0.5);
    51.  
    52.     return base+overlay-mixer;
    53.     }
    54.  
    55.         ENDCG
    56.     }
    57.     }
    58. }
     
    Last edited: Sep 24, 2016
  23. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Can't you just use:

    Blend DstColor SrcColor // 2x Multiplicative

    Which doesn't use a grab pass. Then 0.5 output values are no change, above that is lighten, below is darken.

    This is what we use to do with multi-pass detail textures, back in the day.
     
  24. anisthya

    anisthya

    Joined:
    May 20, 2017
    Posts:
    3
    I'm doing an x-ray shader, I got this code, but for what I want it's incomplete. Here's the shader website:
    http://www.photonworkshop.com/index.php/blog/x-ray-shader/

    My knowledge in shader is pretty basic, I'm studying weeks in Unity documentation and in various tutorials, but nothing comes close to what I need.

    I need to make if one object is on top of the other the color turns green, in addition to having a density control of the material that makes it darker or lighter, and the same with the color intersected.
    And to finish the possibility of putting a texture in black and white and have an individual control the internal with these same characteristics. If you can help me, thank you.
    I tried via C # to change the color, but there remained a wagon hehehehhehehe.
    This is what I have.

    This is what I want to do.


    I tried to merge the idea of the overlay shader, but it did not work like I did. This was the idea on the internet closest to the control I want. I needed to know how to get pixel rendering from the scene and compare with conditionals, or if you think of something better with merges give me a touch. Thank you.
     
  25. robtl

    robtl

    Joined:
    Aug 3, 2017
    Posts:
    2
    Shader "Unlit/Overlay"
    {
    Properties
    {
    _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
    Tags { "RenderType"="Transparent" "Queue"="Transparent"}
    Zwrite off
    LOD 100

    Pass
    {
    Blend SrcAlpha One

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    #include "UnityCG.cginc"

    fixed getAddValue(fixed value){
    fixed v = value;

    if(v<0.5)v=0.5;

    return 2*(v-0.5);
    }

    struct appdata
    {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    };

    struct v2f
    {
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;
    };

    sampler2D _MainTex;float4 _MainTex_ST;

    v2f vert (appdata v)
    {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    return o;
    }

    fixed4 frag (v2f i) : SV_Target
    {
    fixed4 texCol = tex2D(_MainTex, i.uv);

    fixed4 col = fixed4(getAddValue(texCol.r),getAddValue(texCol.g),getAddValue(texCol.b),getAddValue(texCol.a));
    return col;
    }
    ENDCG
    }

    Pass
    {
    Blend DstColor Zero

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    #include "UnityCG.cginc"

    fixed getAddValue(fixed value){
    fixed v = value;

    if(v>0.5)v=0.5;

    return 2*v;
    }

    struct appdata
    {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    };

    struct v2f
    {
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;
    };

    sampler2D _MainTex;float4 _MainTex_ST;

    v2f vert (appdata v)
    {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    return o;
    }

    fixed4 frag (v2f i) : SV_Target
    {
    fixed4 texCol = tex2D(_MainTex, i.uv);

    fixed4 col = fixed4(getAddValue(texCol.r),getAddValue(texCol.g),getAddValue(texCol.b),getAddValue(texCol.a));
    return col;
    }
    ENDCG
    }
    }
    }
     
  26. robtl

    robtl

    Joined:
    Aug 3, 2017
    Posts:
    2
    Two pass is better than GrabTexture