Search Unity

[Solved] Dynamic Blurred Background on UI

Discussion in 'UGUI & TextMesh Pro' started by Plexus1, Aug 2, 2015.

  1. Plexus1

    Plexus1

    Joined:
    Mar 9, 2014
    Posts:
    26
    HI,

    Ive been searching the web on how to blur the background of a UI element dynamically (not a static image) using uGUI in personal edition like this but have not found anything easy to follow


    Does anyone know any ways how I could accomplish this?

    Thanks
     
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Image effect?
     
  3. Plexus1

    Plexus1

    Joined:
    Mar 9, 2014
    Posts:
    26
    How would i get an image effect to apply to the background of the UI? Doesn't it affect the whole camera?
     
  4. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    It does, which is why I used seperate cameras and canvases myself. However, my effect was full-screen, and requires Unity 5 (not 4.6+) to work in the personal edition.

    Perhaps a shader would be more appropriate here. I think there's a default "frosted glass" one for UI, so that might be a good base to build off of. If all else fails, you might also use a grab pass and blur that, though I'm not sure on the performance implications of that.
     
    smit_kareliya likes this.
  5. Giometric

    Giometric

    Joined:
    Dec 20, 2011
    Posts:
    170
    There is a shared GrabPass method you can use. What it does is create a GrabPass render only once using a name, and any shaders that use the same named Grab Pass texture will be able to re-use it without rendering it again. Doing it that way would mean you can only have one 'layer' of blur, but it'll be much faster if you're going to have a number of panels doing blurring.
     
    smit_kareliya and Senshi like this.
  6. Plexus1

    Plexus1

    Joined:
    Mar 9, 2014
    Posts:
    26
    Ok Thanks seems like a better approach, will give it a go!
     
  7. Megagamefan100

    Megagamefan100

    Joined:
    Oct 24, 2012
    Posts:
    26
    I found out how to do this :D

    Note: This method is buggy, and probably not the best way of doing this.

    I am using Unity 5 for this, this is a photo I took of what I did (Not the best)



    You will need:
    Unity 5.
    The Shader I used (Found it on the forums, I can't remember the creators name).
    Basic Unity UI knowledge.
    You need to be human (Sorry Zombies :/)


    Okay let's get started :D

    First, make a new shader and put this code in it
    Code (CSharp):
    1. Shader "Custom/SimpleGrabPassBlur" {
    2.     Properties {
    3.         _Color ("Main Color", Color) = (1,1,1,1)
    4.         _BumpAmt  ("Distortion", Range (0,128)) = 10
    5.         _MainTex ("Tint Color (RGB)", 2D) = "white" {}
    6.         _BumpMap ("Normalmap", 2D) = "bump" {}
    7.         _Size ("Size", Range(0, 20)) = 1
    8.     }
    9.  
    10.     Category {
    11.  
    12.         // We must be transparent, so other objects are drawn before this one.
    13.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Opaque" }
    14.  
    15.  
    16.         SubShader {
    17.      
    18.             // Horizontal blur
    19.             GrabPass {                    
    20.                 Tags { "LightMode" = "Always" }
    21.             }
    22.             Pass {
    23.                 Tags { "LightMode" = "Always" }
    24.              
    25.                 CGPROGRAM
    26.                 #pragma vertex vert
    27.                 #pragma fragment frag
    28.                 #pragma fragmentoption ARB_precision_hint_fastest
    29.                 #include "UnityCG.cginc"
    30.              
    31.                 struct appdata_t {
    32.                     float4 vertex : POSITION;
    33.                     float2 texcoord: TEXCOORD0;
    34.                 };
    35.              
    36.                 struct v2f {
    37.                     float4 vertex : POSITION;
    38.                     float4 uvgrab : TEXCOORD0;
    39.                 };
    40.              
    41.                 v2f vert (appdata_t v) {
    42.                     v2f o;
    43.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    44.                     #if UNITY_UV_STARTS_AT_TOP
    45.                     float scale = -1.0;
    46.                     #else
    47.                     float scale = 1.0;
    48.                     #endif
    49.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    50.                     o.uvgrab.zw = o.vertex.zw;
    51.                     return o;
    52.                 }
    53.              
    54.                 sampler2D _GrabTexture;
    55.                 float4 _GrabTexture_TexelSize;
    56.                 float _Size;
    57.              
    58.                 half4 frag( v2f i ) : COLOR {
    59. //                  half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    60. //                  return col;
    61.                  
    62.                     half4 sum = half4(0,0,0,0);
    63.                     #define GRABPIXEL(weight,kernelx) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx*_Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
    64.                     sum += GRABPIXEL(0.05, -4.0);
    65.                     sum += GRABPIXEL(0.09, -3.0);
    66.                     sum += GRABPIXEL(0.12, -2.0);
    67.                     sum += GRABPIXEL(0.15, -1.0);
    68.                     sum += GRABPIXEL(0.18,  0.0);
    69.                     sum += GRABPIXEL(0.15, +1.0);
    70.                     sum += GRABPIXEL(0.12, +2.0);
    71.                     sum += GRABPIXEL(0.09, +3.0);
    72.                     sum += GRABPIXEL(0.05, +4.0);
    73.                  
    74.                     return sum;
    75.                 }
    76.                 ENDCG
    77.             }
    78.             // Vertical blur
    79.             GrabPass {                        
    80.                 Tags { "LightMode" = "Always" }
    81.             }
    82.             Pass {
    83.                 Tags { "LightMode" = "Always" }
    84.              
    85.                 CGPROGRAM
    86.                 #pragma vertex vert
    87.                 #pragma fragment frag
    88.                 #pragma fragmentoption ARB_precision_hint_fastest
    89.                 #include "UnityCG.cginc"
    90.              
    91.                 struct appdata_t {
    92.                     float4 vertex : POSITION;
    93.                     float2 texcoord: TEXCOORD0;
    94.                 };
    95.              
    96.                 struct v2f {
    97.                     float4 vertex : POSITION;
    98.                     float4 uvgrab : TEXCOORD0;
    99.                 };
    100.              
    101.                 v2f vert (appdata_t v) {
    102.                     v2f o;
    103.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    104.                     #if UNITY_UV_STARTS_AT_TOP
    105.                     float scale = -1.0;
    106.                     #else
    107.                     float scale = 1.0;
    108.                     #endif
    109.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    110.                     o.uvgrab.zw = o.vertex.zw;
    111.                     return o;
    112.                 }
    113.              
    114.                 sampler2D _GrabTexture;
    115.                 float4 _GrabTexture_TexelSize;
    116.                 float _Size;
    117.              
    118.                 half4 frag( v2f i ) : COLOR {
    119. //                  half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    120. //                  return col;
    121.                  
    122.                     half4 sum = half4(0,0,0,0);
    123.                     #define GRABPIXEL(weight,kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely*_Size, i.uvgrab.z, i.uvgrab.w))) * weight
    124.                     //G(X) = (1/(sqrt(2*PI*deviation*deviation))) * exp(-(x*x / (2*deviation*deviation)))
    125.                  
    126.                     sum += GRABPIXEL(0.05, -4.0);
    127.                     sum += GRABPIXEL(0.09, -3.0);
    128.                     sum += GRABPIXEL(0.12, -2.0);
    129.                     sum += GRABPIXEL(0.15, -1.0);
    130.                     sum += GRABPIXEL(0.18,  0.0);
    131.                     sum += GRABPIXEL(0.15, +1.0);
    132.                     sum += GRABPIXEL(0.12, +2.0);
    133.                     sum += GRABPIXEL(0.09, +3.0);
    134.                     sum += GRABPIXEL(0.05, +4.0);
    135.                  
    136.                     return sum;
    137.                 }
    138.                 ENDCG
    139.             }
    140.          
    141.             // Distortion
    142.             GrabPass {                        
    143.                 Tags { "LightMode" = "Always" }
    144.             }
    145.             Pass {
    146.                 Tags { "LightMode" = "Always" }
    147.              
    148.                 CGPROGRAM
    149.                 #pragma vertex vert
    150.                 #pragma fragment frag
    151.                 #pragma fragmentoption ARB_precision_hint_fastest
    152.                 #include "UnityCG.cginc"
    153.              
    154.                 struct appdata_t {
    155.                     float4 vertex : POSITION;
    156.                     float2 texcoord: TEXCOORD0;
    157.                 };
    158.              
    159.                 struct v2f {
    160.                     float4 vertex : POSITION;
    161.                     float4 uvgrab : TEXCOORD0;
    162.                     float2 uvbump : TEXCOORD1;
    163.                     float2 uvmain : TEXCOORD2;
    164.                 };
    165.              
    166.                 float _BumpAmt;
    167.                 float4 _BumpMap_ST;
    168.                 float4 _MainTex_ST;
    169.              
    170.                 v2f vert (appdata_t v) {
    171.                     v2f o;
    172.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    173.                     #if UNITY_UV_STARTS_AT_TOP
    174.                     float scale = -1.0;
    175.                     #else
    176.                     float scale = 1.0;
    177.                     #endif
    178.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    179.                     o.uvgrab.zw = o.vertex.zw;
    180.                     o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
    181.                     o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
    182.                     return o;
    183.                 }
    184.              
    185.                 fixed4 _Color;
    186.                 sampler2D _GrabTexture;
    187.                 float4 _GrabTexture_TexelSize;
    188.                 sampler2D _BumpMap;
    189.                 sampler2D _MainTex;
    190.              
    191.                 half4 frag( v2f i ) : COLOR {
    192.                     // calculate perturbed coordinates
    193.                     half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg; // we could optimize this by just reading the x  y without reconstructing the Z
    194.                     float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
    195.                     i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    196.                  
    197.                     half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    198.                     half4 tint = tex2D( _MainTex, i.uvmain ) * _Color;
    199.                  
    200.                     return col * tint;
    201.                 }
    202.                 ENDCG
    203.             }
    204.         }
    205.     }
    206. }
    Now make a new Material and put the shader you made on it.

    Make a button (This button will be used as a test)
    Then make a Panel, scale the Panel to the size of the button, now drag the button inside of the Panel.

    Now go to the panel and remove it's Source Image, and set the Material to the Material that has the blur shader.
    Also make the button see transparent or something so you can see the blur effect, now you should be done :D

    Sorry for bad spelling :/ and grammar.







     
  8. Plexus1

    Plexus1

    Joined:
    Mar 9, 2014
    Posts:
    26
    Awesome this is exactly what I was looking for! Thanks! :)
     
    UnderscoreA and cetaceo_rafael like this.
  9. Megagamefan100

    Megagamefan100

    Joined:
    Oct 24, 2012
    Posts:
    26
    :D happy to help!
     
    UnderscoreA likes this.
  10. p4vlos

    p4vlos

    Joined:
    Dec 10, 2015
    Posts:
    5
    Does the screen is mirror when you run the game? or maybe is the graphics of my computer that are wrong?
     
  11. Vlad3489

    Vlad3489

    Joined:
    Dec 24, 2014
    Posts:
    5
    Usefull shader. Does it support masking? For example if you want to create blur with specific shape. It's will be great
     
  12. p4vlos

    p4vlos

    Joined:
    Dec 10, 2015
    Posts:
    5
    Now when I run it became a black canvas. Can you help me for this? thank you so much
     
  13. p4vlos

    p4vlos

    Joined:
    Dec 10, 2015
    Posts:
    5
    when I run it became a black canvas. Can you help me for this? thank you so much
     
  14. Chintao

    Chintao

    Joined:
    Jun 26, 2014
    Posts:
    54
    UnderscoreA likes this.
  15. EParent

    EParent

    Joined:
    Feb 13, 2015
    Posts:
    36
    Thank you so much. Exactly what I want =)
     
  16. flyhog

    flyhog

    Joined:
    Aug 10, 2015
    Posts:
    2
  17. fred_gds

    fred_gds

    Joined:
    Sep 20, 2012
    Posts:
    184
    Thank you!!! :)
     
  18. crispybeans

    crispybeans

    Joined:
    Apr 13, 2015
    Posts:
    210
    This looks really good, would it be possible to add an amount of iterations so the blur spreads much more ?
     
  19. devravenio

    devravenio

    Joined:
    Jun 9, 2014
    Posts:
    11
    it has performance issue on mobile.
    it is eating 20fps.

    any alternatives?
     
  20. pedroahpolonio

    pedroahpolonio

    Joined:
    Sep 26, 2015
    Posts:
    1
    I have what I believe to be a lighter version of Megagamefan100's solution:

    Code (CSharp):
    1. Shader "Unlit/FrostedGlass"
    2. {
    3.     Properties
    4.     {
    5.         _Radius("Radius", Range(1, 255)) = 1
    6.     }
    7.  
    8.     Category
    9.     {
    10.         Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
    11.      
    12.         SubShader
    13.         {
    14.             GrabPass
    15.             {
    16.                 Tags{ "LightMode" = "Always" }
    17.             }
    18.  
    19.             Pass
    20.             {
    21.                 Tags{ "LightMode" = "Always" }
    22.  
    23.                 CGPROGRAM
    24.                 #pragma vertex vert
    25.                 #pragma fragment frag
    26.                 #pragma fragmentoption ARB_precision_hint_fastest
    27.                 #include "UnityCG.cginc"
    28.  
    29.                 struct appdata_t
    30.                 {
    31.                     float4 vertex : POSITION;
    32.                     float2 texcoord: TEXCOORD0;
    33.                 };
    34.  
    35.                 struct v2f
    36.                 {
    37.                     float4 vertex : POSITION;
    38.                     float4 uvgrab : TEXCOORD0;
    39.                 };
    40.  
    41.                 v2f vert(appdata_t v)
    42.                 {
    43.                     v2f o;
    44.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    45.                     #if UNITY_UV_STARTS_AT_TOP
    46.                     float scale = -1.0;
    47.                     #else
    48.                     float scale = 1.0;
    49.                     #endif
    50.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    51.                     o.uvgrab.zw = o.vertex.zw;
    52.                     return o;
    53.                 }
    54.  
    55.                 sampler2D _GrabTexture;
    56.                 float4 _GrabTexture_TexelSize;
    57.                 float _Radius;
    58.  
    59.                 half4 frag(v2f i) : COLOR
    60.                 {
    61.                     half4 sum = half4(0,0,0,0);
    62.  
    63.                     #define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))
    64.  
    65.                     sum += GRABXYPIXEL(0.0, 0.0);
    66.                     int measurments = 1;
    67.  
    68.                     for (float range = 0.1f; range <= _Radius; range += 0.1f)
    69.                     {
    70.                         sum += GRABXYPIXEL(range, range);
    71.                         sum += GRABXYPIXEL(range, -range);
    72.                         sum += GRABXYPIXEL(-range, range);
    73.                         sum += GRABXYPIXEL(-range, -range);
    74.                         measurments += 4;
    75.                     }
    76.  
    77.                     return sum / measurments;
    78.                 }
    79.                 ENDCG
    80.             }
    81.             GrabPass
    82.             {
    83.                 Tags{ "LightMode" = "Always" }
    84.             }
    85.  
    86.             Pass
    87.             {
    88.                 Tags{ "LightMode" = "Always" }
    89.  
    90.                 CGPROGRAM
    91.                 #pragma vertex vert
    92.                 #pragma fragment frag
    93.                 #pragma fragmentoption ARB_precision_hint_fastest
    94.                 #include "UnityCG.cginc"
    95.  
    96.                 struct appdata_t
    97.                 {
    98.                     float4 vertex : POSITION;
    99.                     float2 texcoord: TEXCOORD0;
    100.                 };
    101.  
    102.                 struct v2f
    103.                 {
    104.                     float4 vertex : POSITION;
    105.                     float4 uvgrab : TEXCOORD0;
    106.                 };
    107.  
    108.                 v2f vert(appdata_t v)
    109.                 {
    110.                     v2f o;
    111.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    112.                     #if UNITY_UV_STARTS_AT_TOP
    113.                     float scale = -1.0;
    114.                     #else
    115.                     float scale = 1.0;
    116.                     #endif
    117.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    118.                     o.uvgrab.zw = o.vertex.zw;
    119.                     return o;
    120.                 }
    121.  
    122.                 sampler2D _GrabTexture;
    123.                 float4 _GrabTexture_TexelSize;
    124.                 float _Radius;
    125.  
    126.                 half4 frag(v2f i) : COLOR
    127.                 {
    128.  
    129.                     half4 sum = half4(0,0,0,0);
    130.                     float radius = 1.41421356237 * _Radius;
    131.  
    132.                     #define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))
    133.  
    134.                     sum += GRABXYPIXEL(0.0, 0.0);
    135.                     int measurments = 1;
    136.  
    137.                     for (float range = 1.41421356237f; range <= radius * 1.41; range += 1.41421356237f)
    138.                     {
    139.                         sum += GRABXYPIXEL(range, 0);
    140.                         sum += GRABXYPIXEL(-range, 0);
    141.                         sum += GRABXYPIXEL(0, range);
    142.                         sum += GRABXYPIXEL(0, -range);
    143.                         measurments += 4;
    144.                     }
    145.  
    146.                     return sum / measurments;
    147.                 }
    148.                 ENDCG
    149.             }
    150.         }
    151.     }
    152. }
    153.  
    As you can see, most properties are now gone.

    Initially, I made it with variable resolution, but, as I could hardly see any improvements in the result as the resolution climbed, I ended up dropping it and sticking to a fixed resolution. I also like that this version produces less of a "mosaic" effect and more of a "circular blur".

    Let me know if this works better for you.
     
    Last edited: Nov 15, 2016
  21. Mr_Orange

    Mr_Orange

    Joined:
    Jan 8, 2015
    Posts:
    5
    Hi folks,
    apparantely this is exactly what I am looking for.

    Unfortunately I seem to be to less experienced to get it to work.... I tried creating a C# script with the code from above but I am not surprised that Visual Studio gives me errors as this does not follow usual C# class requirements and hence returns Unity returns with a Parsing Error.

    I also tried the "NewComputeShader" and put the code into the section where it says "// TODO: insert actual code here!".

    Some advice would be appreciated!
    Thanks!

    EDIT:
    Never mind. Got it to work. Hint: Use either "Standard Surface Shader" oder "Unlit Shader".

    Nice work guys!

    Other question: Can I somehow control the degree of blurriness of the shader? Went through the code and only thing that does make sense to me would be chaning the value of "measurments" variable...

    Thanks again!
     
  22. lokinwai

    lokinwai

    Joined:
    Feb 11, 2015
    Posts:
    174
    I try to use image effect to do it. Using lower resolution render texture, it can have higher performance.

    here the code extend StandardAssets BlurOptimized to steal the result to a render texture.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityStandardAssets.ImageEffects;
    3.  
    4. public class Blur2RT : BlurOptimized
    5. {
    6.     public RenderTexture renderTexture = null;
    7.     public bool renderTextureOnly = true;
    8.  
    9.     new void Start()
    10.     {
    11.         base.Start();
    12.         blurShader = Shader.Find("Hidden/FastBlur");
    13.  
    14.         if (blurShader == null)
    15.             enabled = false;
    16.     }
    17.  
    18.     public new void OnRenderImage(RenderTexture source, RenderTexture destination)
    19.     {
    20.  
    21.         if (renderTexture != null)
    22.             base.OnRenderImage(source, renderTexture);
    23.         if (renderTextureOnly)
    24.         {
    25.             Graphics.Blit(source, destination);
    26.             return;
    27.         }
    28.         if (renderTexture == null)
    29.             base.OnRenderImage(source, destination);
    30.         else
    31.             Graphics.Blit(renderTexture, destination);
    32.     }
    33. }
    34.  
    Then, you can use the render texture as the background of the UI.

    I modified the build-in shader of UI/Lit/Refraction Detail.

    Code (CSharp):
    1. Shader "UI/Lit/Refraction Detail (BG)"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _Specular ("Specular Color", Color) = (0,0,0,0)
    7.         _MainTex ("Diffuse (RGB), Alpha (A)", 2D) = "white" {}
    8.         _MainBump ("Diffuse Bump Map", 2D) = "bump" {}
    9.         _Mask ("Mask (Specularity, Shininess, Refraction)", 2D) = "white" {}
    10.         _DetailTex ("Detail (RGB)", 2D) = "white" {}
    11.         _DetailBump ("Detail Bump Map", 2D) = "bump" {}
    12.         _DetailMask ("Detail Mask (Spec, Shin, Ref)", 2D) = "white" {}
    13.         _BGTex ("Background", 2D) = "clear" {}
    14.         _Shininess ("Shininess", Range(0.01, 1.0)) = 0.2
    15.         _Focus ("Focus", Range(-100.0, 100.0)) = -100.0
    16.      
    17.         _StencilComp ("Stencil Comparison", Float) = 8
    18.         _Stencil ("Stencil ID", Float) = 0
    19.         _StencilOp ("Stencil Operation", Float) = 0
    20.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    21.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    22.  
    23.         _ColorMask ("Color Mask", Float) = 15
    24.  
    25.         [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    26.     }
    27.  
    28.     // SM 3.0
    29.     SubShader
    30.     {
    31.         LOD 300
    32.  
    33.         Tags
    34.         {
    35.             "Queue" = "Transparent"
    36.             "IgnoreProjector" = "True"
    37.             "RenderType" = "Transparent"
    38.             "PreviewType"="Plane"
    39.         }
    40.  
    41.         Stencil
    42.         {
    43.             Ref [_Stencil]
    44.             Comp [_StencilComp]
    45.             Pass [_StencilOp]
    46.             ReadMask [_StencilReadMask]
    47.             WriteMask [_StencilWriteMask]
    48.         }
    49.      
    50.         Cull Off
    51.         Lighting Off
    52.         ZWrite Off
    53.         ZTest [unity_GUIZTestMode]
    54.         Blend SrcAlpha OneMinusSrcAlpha
    55.         ColorMask [_ColorMask]
    56.  
    57.         CGPROGRAM
    58.             #pragma target 3.0
    59.             #pragma surface surf PPL alpha noshadow novertexlights nolightmap vertex:vert nofog
    60.              
    61.             #include "UnityCG.cginc"
    62.             #include "UnityUI.cginc"
    63.  
    64.             #pragma multi_compile __ UNITY_UI_ALPHACLIP
    65.  
    66.             struct appdata_t
    67.             {
    68.                 float4 vertex : POSITION;
    69.                 float2 texcoord1 : TEXCOORD0;
    70.                 float2 texcoord2 : TEXCOORD1;
    71.                 fixed4 color : COLOR;
    72.                 float3 normal : NORMAL;
    73.                 float4 tangent : TANGENT;
    74.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    75.             };
    76.  
    77.             struct Input
    78.             {
    79.                 float4 texcoord1;
    80.                 float4 texcoord2;
    81.                 float2 texcoord3;
    82.                 float4 proj;
    83.                 fixed4 color : COLOR;
    84.                 float4 worldPosition;
    85.             };
    86.  
    87.             sampler2D _GrabTexture;
    88.             sampler2D _MainTex;
    89.             sampler2D _MainBump;
    90.             sampler2D _Mask;
    91.             sampler2D _DetailTex;
    92.             sampler2D _DetailBump;
    93.             sampler2D _DetailMask;
    94.             sampler2D _BGTex;
    95.  
    96.             float4 _MainTex_ST;
    97.             float4 _MainBump_ST;
    98.             float4 _Mask_ST;
    99.             float4 _DetailTex_ST;
    100.             float4 _DetailBump_ST;
    101.             float4 _DetailMask_ST;
    102.             float4 _DetailTex_TexelSize;
    103.             float4 _DetailBump_TexelSize;
    104.             float4 _DetailMask_TexelSize;
    105.             float4 _BGTex_TexelSize;
    106.  
    107.             fixed4 _Color;
    108.             fixed4 _Specular;
    109.             half _Shininess;
    110.             half _Focus;
    111.  
    112.             fixed4 _TextureSampleAdd;
    113.             float4 _ClipRect;
    114.  
    115.             void vert (inout appdata_t v, out Input o)
    116.             {
    117.                 UNITY_INITIALIZE_OUTPUT(Input, o);
    118.                 o.worldPosition = v.vertex;
    119.                 v.vertex = o.worldPosition;
    120.                 v.color = v.color * _Color;
    121.  
    122.                 o.texcoord1.xy    = TRANSFORM_TEX(v.texcoord1, _MainTex);
    123.                 o.texcoord1.zw    = TRANSFORM_TEX(v.texcoord1, _MainBump);
    124.                 o.texcoord2.xy    = TRANSFORM_TEX(v.texcoord2 * _DetailTex_TexelSize.xy, _DetailTex);
    125.                 o.texcoord2.zw    = TRANSFORM_TEX(v.texcoord2 * _DetailBump_TexelSize.xy, _DetailBump);
    126.                 o.texcoord3        = TRANSFORM_TEX(v.texcoord2 * _DetailMask_TexelSize.xy, _DetailMask);
    127.  
    128.                 o.proj = ComputeScreenPos(mul(UNITY_MATRIX_MVP, v.vertex));
    129.             }
    130.  
    131.             void surf (Input IN, inout SurfaceOutput o)
    132.             {
    133.                 fixed4 col = tex2D(_MainTex, IN.texcoord1.xy) + _TextureSampleAdd;
    134.                 fixed4 detail = tex2D(_DetailTex, IN.texcoord2.xy);
    135.  
    136.                 half3 normal = UnpackNormal(tex2D(_MainBump, IN.texcoord1.zw)) +
    137.                                UnpackNormal(tex2D(_DetailBump, IN.texcoord2.zw));
    138.              
    139.                 half3 mask = tex2D(_Mask, IN.texcoord1.xy) *
    140.                              tex2D(_DetailMask, IN.texcoord3);
    141.  
    142.                 float2 offset = normal.xy * _BGTex_TexelSize.xy * _Focus;
    143.                 IN.proj.xy = offset * IN.proj.z + IN.proj.xy;
    144.                 half4 ref = tex2Dproj(_BGTex, UNITY_PROJ_COORD(IN.proj));
    145.  
    146.                 col.rgb = lerp(col.rgb, ref.rgb, mask.b);
    147.                 col.rgb = lerp(col.rgb, col.rgb * detail.rgb, detail.a);
    148.                 col *= IN.color;
    149.                  
    150.                 o.Albedo = col.rgb;
    151.                 o.Normal = normalize(normal);
    152.                 o.Specular = _Specular.a * mask.r;
    153.                 o.Gloss = _Shininess * mask.g;
    154.                 o.Alpha = col.a;
    155.      
    156.                 o.Alpha *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
    157.              
    158.                 #ifdef UNITY_UI_ALPHACLIP
    159.                 clip (o.Alpha - 0.001);
    160.                 #endif
    161.             }
    162.  
    163.             half4 LightingPPL (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
    164.             {
    165.                 half3 nNormal = normalize(s.Normal);
    166.                 half shininess = s.Gloss * 250.0 + 4.0;
    167.  
    168.             #ifndef USING_DIRECTIONAL_LIGHT
    169.                 lightDir = normalize(lightDir);
    170.             #endif
    171.  
    172.                 // Phong shading model
    173.                 half reflectiveFactor = max(0.0, dot(-viewDir, reflect(lightDir, nNormal)));
    174.  
    175.                 // Blinn-Phong shading model
    176.                 //half reflectiveFactor = max(0.0, dot(nNormal, normalize(lightDir + viewDir)));
    177.              
    178.                 half diffuseFactor = max(0.0, dot(nNormal, lightDir));
    179.                 half specularFactor = pow(reflectiveFactor, shininess) * s.Specular;
    180.  
    181.                 half4 c;
    182.                 c.rgb = (s.Albedo * diffuseFactor + _Specular.rgb * specularFactor) * _LightColor0.rgb;
    183.                 c.rgb *= atten;
    184.                 c.a = s.Alpha;
    185.                 return c;
    186.             }
    187.         ENDCG
    188.     }
    189.     Fallback "UI/Lit/Detail"
    190. }
    191.  
    I modified a sample in "Unity Samples: UI" from asset store, and the result:

    Render_2017-01-04_05-42-07_.jpg

    You can use other image effect to do the UI background, here is a old paint effect:

    Render_2017-01-04_08-24-40_.jpg
     
  23. Baelgren

    Baelgren

    Joined:
    Jun 26, 2014
    Posts:
    5
    Do you have a little tutorial somewhere for how to use this in a scene?
     
  24. WarpZone

    WarpZone

    Joined:
    Oct 29, 2007
    Posts:
    326
    Downloaded the UnityUI Standard Example package. Opened the scene Lighting.Unity, used in your first screenshot. Recreated your shader and C# script.

    When I make your shader with this in Unity, it says:

    The line in the shader throwing the error is just:
    Commenting this out causes the shader to compile, but there is no blur effect.

    Google led me to this: `UNITY_VERTEX_INPUT_INSTANCE_ID` should be `UNITY_INSTANCE_ID` in Unity 5.4

    Replaced with UNITY_INSTANCE_ID, and this caused the shader to compile again.

    Still no blur effect when this shader is used on a UIPanel. (Panel was hot pink when the shader was broken so I know my scene is set up correctly.)

    If you turn off "Render Texture Only," it blurs the whole screen, so we know that part is working correctly.

    Messing around with the graphics options in the Player, it seemed like Forward Rendering makes this look like the normal transparent lightmapped UI demo with no blurring, and Deferred rendering makes everything but the UI completely black. Neither one makes it look how it's supposed to look.

    Noticed that when I attach the Blur2RT script to a camera, it disables itself. Looking at the script, apparently Shader.Find("Hidden/FastBlur") is returning null.

    Can't find a "Hidden" directory anywhere, even though the fullscreen blur works fine. Made sure my UI Examples package was up-to-date. Downloaded all shaders from the Standard Assets package, even obscure ones like the Water ones that I don't need. Still no Hidden/FastBlur.

    Come to think of it, there is already a shader plugged into the Blur2RT script! Clicking "Hidden/FastBlur" in the Inspector highlights MobileBlur in the Project View. Source code of MobileBlur does indeed call it "Hidden/FastBlur." WTF? Google says the "Hidden/" prefix doesn't do anything unless there's an actual physical folder in your project named "Hidden." This came from users' comments though, so maybe it's true in an older version of Unity?

    Tried renaming it to MobileBlur, but that just made things... more broken? Unity acted like it was null in more ways, if that makes sense. (Which it doesn't.) Apparently Unity is wiring up the shader correctly, just the C# script doesn't know it. Tried to use Debug.Log before the line to disable the script, but it never fires even though the script-disabling line apparently does. Commented out enabled = false in Blur2RT.

    Now if you attach Blur2RT to your Main camera and disable the RenderTexture option, (which I have never been able to get to work with this guy's code) it blurs the whole screen (not just the menu portion) but I think it was already possible to do this using the standard shaders and two cameras.

    Suddenly realized that the "Missing shader in Background (Blur2RT)" error is coming from the Unity Editor, NOT from the C# script. Unity itself is declaring Hidden/FastBlur "missing" and disabling the script, apparently doing automatically what the C# script was trying to do manually until I commented it out. I'm cold, I'm hungry, I'm tired, and this goddamned code doesn't work.

    Tested on Unity 5.4.4.f1 Personal.
     
    Last edited: Feb 4, 2017
  25. Zythus

    Zythus

    Joined:
    Jun 28, 2014
    Posts:
    30
    Unfortunately can't help you, but I'm looking for help myself, I have got a flying game and when plane is boosting I want the screen around it to blur (like it does in car games, CSR, Asphalt, etc.). How would you guys go about that?
     
  26. WarpZone

    WarpZone

    Joined:
    Oct 29, 2007
    Posts:
    326
    There's already a Motion Blur system in Unity, would that work for your purposes? Google Unity+Motion Blur
     
  27. Zythus

    Zythus

    Joined:
    Jun 28, 2014
    Posts:
    30
    I'll look around for a tutorial covering exactly what I want, since I tried that blur system but it blurs whole camera, I'll just tinker with it, thanks anyways.
     
  28. lokinwai

    lokinwai

    Joined:
    Feb 11, 2015
    Posts:
    174
    Do you create a render texture and set it to Blur2RT?

    rendertexture.jpg
     
  29. Gilwing

    Gilwing

    Joined:
    Jun 21, 2014
    Posts:
    2
    This is exactly what I was looking for! Thanks a ton! As I have no knowledge of shaders I was trying to tweak Megagamefan100's shader's blur intensity with no success and then I saw your solution which can tweak it straight from the UI which is awesome! Once again, thanks!
     
    UnderscoreA likes this.
  30. Aminushki

    Aminushki

    Joined:
    Jun 10, 2016
    Posts:
    11
    hey its been a while but im experiencing a bug with your shader, if it is in any scene, and then i load into another scene and comeback, the shader is broken, as in the object it was on turns invisible(panel), any help would be great
     
  31. Swinguru_FX

    Swinguru_FX

    Joined:
    Mar 31, 2014
    Posts:
    9
    Worked like a charm, thank you !
     
    UnderscoreA likes this.
  32. vinipc

    vinipc

    Joined:
    Jun 21, 2013
    Posts:
    8
    I think Megagamefan100 solution used cician's shader from another thread ( https://forum.unity3d.com/threads/simple-optimized-blur-shader.185327/#post-1267642).
    I recently had to use it, but I needed to mask it as well, so I modified it a bit to use the Image's alpha to affect the blur. Might be useful for someone else.

    ( @Vlad3489 this one has masking, if you still need it somehow)

    Two notes however:
    1) Because of the grab passes, it is pretty much unusable on iOS (and maybe Android as well. I haven't tested).
    2) I made this to use with Unity's UI Image component. If you need it for something else, you can probably remove the [HideInInspector] property from the _MainTex.

    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3. // Based on cician's shader from: https://forum.unity3d.com/threads/simple-optimized-blur-shader.185327/#post-1267642
    4.  
    5. Shader "Custom/MaskedUIBlur" {
    6.     Properties {
    7.         _Size ("Blur", Range(0, 30)) = 1
    8.         [HideInInspector] _MainTex ("Tint Color (RGB)", 2D) = "white" {}
    9.     }
    10.  
    11.     Category {
    12.  
    13.         // We must be transparent, so other objects are drawn before this one.
    14.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Opaque" }
    15.  
    16.  
    17.         SubShader
    18.         {
    19.             // Horizontal blur
    20.             GrabPass
    21.             {
    22.                 "_HBlur"
    23.             }
    24.  
    25.             Pass
    26.             {          
    27.                 CGPROGRAM
    28.                 #pragma vertex vert
    29.                 #pragma fragment frag
    30.                 #pragma fragmentoption ARB_precision_hint_fastest
    31.                 #include "UnityCG.cginc"
    32.          
    33.                 struct appdata_t {
    34.                     float4 vertex : POSITION;
    35.                     float2 texcoord: TEXCOORD0;
    36.                 };
    37.          
    38.                 struct v2f {
    39.                     float4 vertex : POSITION;
    40.                     float4 uvgrab : TEXCOORD0;
    41.                     float2 uvmain : TEXCOORD1;
    42.                 };
    43.  
    44.                 sampler2D _MainTex;
    45.                 float4 _MainTex_ST;
    46.  
    47.                 v2f vert (appdata_t v)
    48.                 {
    49.                     v2f o;
    50.                     o.vertex = UnityObjectToClipPos(v.vertex);
    51.  
    52.                     #if UNITY_UV_STARTS_AT_TOP
    53.                     float scale = -1.0;
    54.                     #else
    55.                     float scale = 1.0;
    56.                     #endif
    57.  
    58.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
    59.                     o.uvgrab.zw = o.vertex.zw;
    60.  
    61.                     o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
    62.                     return o;
    63.                 }
    64.          
    65.                 sampler2D _HBlur;
    66.                 float4 _HBlur_TexelSize;
    67.                 float _Size;
    68.  
    69.                 half4 frag( v2f i ) : COLOR
    70.                 {    
    71.                     float alpha = tex2D(_MainTex, i.uvmain).a;
    72.                     half4 sum = half4(0,0,0,0);
    73.  
    74.                     #define GRABPIXEL(weight,kernelx) tex2Dproj( _HBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x + _HBlur_TexelSize.x * kernelx * _Size * alpha, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
    75.  
    76.                     sum += GRABPIXEL(0.05, -4.0);
    77.                     sum += GRABPIXEL(0.09, -3.0);
    78.                     sum += GRABPIXEL(0.12, -2.0);
    79.                     sum += GRABPIXEL(0.15, -1.0);
    80.                     sum += GRABPIXEL(0.18,  0.0);
    81.                     sum += GRABPIXEL(0.15, +1.0);
    82.                     sum += GRABPIXEL(0.12, +2.0);
    83.                     sum += GRABPIXEL(0.09, +3.0);
    84.                     sum += GRABPIXEL(0.05, +4.0);
    85.  
    86.                     return sum ;
    87.                 }
    88.                 ENDCG
    89.             }
    90.  
    91.             // Vertical blur
    92.             GrabPass
    93.             {
    94.                 "_VBlur"
    95.             }
    96.  
    97.             Pass
    98.             {          
    99.                 CGPROGRAM
    100.                 #pragma vertex vert
    101.                 #pragma fragment frag
    102.                 #pragma fragmentoption ARB_precision_hint_fastest
    103.                 #include "UnityCG.cginc"
    104.          
    105.                 struct appdata_t {
    106.                     float4 vertex : POSITION;
    107.                     float2 texcoord: TEXCOORD0;
    108.                 };
    109.          
    110.                 struct v2f {
    111.                     float4 vertex : POSITION;
    112.                     float4 uvgrab : TEXCOORD0;
    113.                     float2 uvmain : TEXCOORD1;
    114.                 };
    115.  
    116.                 sampler2D _MainTex;
    117.                 float4 _MainTex_ST;
    118.  
    119.                 v2f vert (appdata_t v) {
    120.                     v2f o;
    121.                     o.vertex = UnityObjectToClipPos(v.vertex);
    122.  
    123.                     #if UNITY_UV_STARTS_AT_TOP
    124.                     float scale = -1.0;
    125.                     #else
    126.                     float scale = 1.0;
    127.                     #endif
    128.  
    129.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
    130.                     o.uvgrab.zw = o.vertex.zw;
    131.  
    132.                     o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
    133.  
    134.                     return o;
    135.                 }
    136.          
    137.                 sampler2D _VBlur;
    138.                 float4 _VBlur_TexelSize;
    139.                 float _Size;
    140.          
    141.                 half4 frag( v2f i ) : COLOR
    142.                 {
    143.                     float alpha = tex2D(_MainTex, i.uvmain).a;
    144.                     half4 sum = half4(0,0,0,0);
    145.  
    146.                     #define GRABPIXEL(weight,kernely) tex2Dproj( _VBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _VBlur_TexelSize.y * kernely * _Size * alpha, i.uvgrab.z, i.uvgrab.w))) * weight
    147.  
    148.                     sum += GRABPIXEL(0.05, -4.0);
    149.                     sum += GRABPIXEL(0.09, -3.0);
    150.                     sum += GRABPIXEL(0.12, -2.0);
    151.                     sum += GRABPIXEL(0.15, -1.0);
    152.                     sum += GRABPIXEL(0.18,  0.0);
    153.                     sum += GRABPIXEL(0.15, +1.0);
    154.                     sum += GRABPIXEL(0.12, +2.0);
    155.                     sum += GRABPIXEL(0.09, +3.0);
    156.                     sum += GRABPIXEL(0.05, +4.0);
    157.  
    158.                     return sum;
    159.                 }
    160.                 ENDCG
    161.             }
    162.         }
    163.     }
    164. }
     
    CG-JM, Behnamjef, ossobuko and 3 others like this.
  33. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    Very nice!
    When I use a very strong blur I can see a repetitive pattern.
    Any way to solve this? (More samples / subdivisions)
     
    fakegood likes this.
  34. salonimehta

    salonimehta

    Joined:
    Apr 26, 2017
    Posts:
    1
    I used all the shader codes available on this thread, and though they work fine, what it is also doing is that it is making visible my alternate camera through the panel (refer the big purple box in the middle of the screen below). I can't figure out why!
    Can anyone help?
    Screen Shot 2017-05-18 at 1.16.34 PM.png
     
    masakatsu likes this.
  35. vovo801

    vovo801

    Joined:
    Feb 3, 2015
    Posts:
    18
    Huge thanks for great finds in this thread. Is it possible to make this work with a WorldSpace Canvas and Perspective camera?
    I tried Megagamefan100's solution, tried MaskedUIBlur shader by vinipc. The blur shows up correctly when:
    1) The Canvas is set to Overlay, camera is set to Perspective.
    2) Or when the camera is set to Orthographic and Canvas is set to WorldSpace.
    The goal is to blur all the stuff behind the canvas, but still have some non-UI objects in front of the canvas that will not be blurred.
    Any help appreciated.
    UPDATE: problem solved for me, just had to set much higher value of blur. Now that I`ve put blur up to 16, in the Game tab there is a slight blur that I need, but in the scene tab there is extremely high blur, even with artifacts.
     
    Last edited: May 19, 2017
    neurocat likes this.
  36. Drezus

    Drezus

    Joined:
    Oct 14, 2013
    Posts:
    13
    I was looking everywhere for a circular blur like this one, that didn't produce mosaic artifacts. Thanks a ton!
     
    CG-JM likes this.
  37. JeroenKappe

    JeroenKappe

    Joined:
    Dec 13, 2015
    Posts:
    2
    Anyone got a mobile-friendly solution?
     
  38. goldkrestDev

    goldkrestDev

    Joined:
    Feb 6, 2016
    Posts:
    1
    I'm also looking for it!
    You stole my words :)
     
  39. Rodolinc

    Rodolinc

    Joined:
    Sep 23, 2013
    Posts:
    63
    thanks! works perfectly for my needs, Is it hard to add a property for color? (I added the shader to a UI panel and it blurs correctly but would be better if the panel would also have a certain color too)
     
  40. aoo_au

    aoo_au

    Joined:
    Sep 9, 2017
    Posts:
    1
    A little modification to pedroahpolonio's version allowing the shader to tint the colour based on NGUI widget's colour.
    Code (Boo):
    1. Shader "Custom/SimpleGrabPassBlur" {
    2.     Properties
    3.     {
    4.         _Radius("Radius", Range(1, 255)) = 1
    5.     }
    6.     Category
    7.     {
    8.         Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
    9.    
    10.         SubShader
    11.         {
    12.             GrabPass
    13.             {
    14.                 Tags{ "LightMode" = "Always" }
    15.             }
    16.             Pass
    17.             {
    18.                 Tags{ "LightMode" = "Always" }
    19.                  Blend SrcAlpha OneMinusSrcAlpha
    20.  
    21.                 CGPROGRAM
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                 #pragma fragmentoption ARB_precision_hint_fastest
    25.                 #include "UnityCG.cginc"
    26.                 struct appdata_t
    27.                 {
    28.                     float4 vertex : POSITION;
    29.                     float2 texcoord: TEXCOORD0;
    30.                       fixed4 color : COLOR;
    31.                };
    32.                 struct v2f
    33.                 {
    34.                     float4 vertex : POSITION;
    35.                     float4 uvgrab : TEXCOORD0;
    36.                      fixed4 color : COLOR;
    37.                 };
    38.                 v2f vert(appdata_t v)
    39.                 {
    40.                     v2f o;
    41.                     o.vertex = UnityObjectToClipPos(v.vertex);
    42.                     #if UNITY_UV_STARTS_AT_TOP
    43.                     float scale = -1.0;
    44.                     #else
    45.                     float scale = 1.0;
    46.                     #endif
    47.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    48.                     o.uvgrab.zw = o.vertex.zw;
    49.                       o.color = v.color;
    50.                     return o;
    51.                 }
    52.                 sampler2D _GrabTexture;
    53.                 float4 _GrabTexture_TexelSize;
    54.                 float _Radius;
    55.                 half4 frag(v2f i) : COLOR
    56.                 {
    57.                     half4 sum = half4(0,0,0,0);
    58.                     #define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))
    59.                     sum += GRABXYPIXEL(0.0, 0.0);
    60.                     int measurments = 1;
    61.                    
    62.                     for (float range = 0.1f; range <= _Radius; range += 0.1f)
    63.                     {
    64.                         sum += GRABXYPIXEL(range, range);
    65.                         sum += GRABXYPIXEL(range, -range);
    66.                         sum += GRABXYPIXEL(-range, range);
    67.                         sum += GRABXYPIXEL(-range, -range);
    68.                         measurments += 4;
    69.                     }
    70.                     return sum / measurments * i.color;
    71.                 }
    72.                 ENDCG
    73.             }
    74.             GrabPass
    75.             {
    76.                 Tags{ "LightMode" = "Always" }
    77.             }
    78.             Pass
    79.             {
    80.                 Tags{ "LightMode" = "Always" }
    81.                  Blend SrcAlpha OneMinusSrcAlpha
    82.  
    83.                 CGPROGRAM
    84.                 #pragma vertex vert
    85.                 #pragma fragment frag
    86.                 #pragma fragmentoption ARB_precision_hint_fastest
    87.                 #include "UnityCG.cginc"
    88.                 struct appdata_t
    89.                 {
    90.                     float4 vertex : POSITION;
    91.                     float2 texcoord: TEXCOORD0;
    92.                      fixed4 color : COLOR;
    93.                };
    94.                 struct v2f
    95.                 {
    96.                     float4 vertex : POSITION;
    97.                     float4 uvgrab : TEXCOORD0;
    98.                       fixed4 color : COLOR;
    99.               };
    100.                 v2f vert(appdata_t v)
    101.                 {
    102.                     v2f o;
    103.                     o.vertex = UnityObjectToClipPos(v.vertex);
    104.                     #if UNITY_UV_STARTS_AT_TOP
    105.                     float scale = -1.0;
    106.                     #else
    107.                     float scale = 1.0;
    108.                     #endif
    109.                     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    110.                     o.uvgrab.zw = o.vertex.zw;
    111.                       o.color = v.color;
    112.                       return o;
    113.                 }
    114.                 sampler2D _GrabTexture;
    115.                 float4 _GrabTexture_TexelSize;
    116.                 float _Radius;
    117.                 half4 frag(v2f i) : COLOR
    118.                 {
    119.                     half4 sum = half4(0,0,0,0);
    120.                     float radius = 1.41421356237 * _Radius;
    121.                     #define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))
    122.                     sum += GRABXYPIXEL(0.0, 0.0);
    123.                     int measurments = 1;
    124.  
    125.                     for (float range = 1.41421356237f; range <= radius * 1.41; range += 1.41421356237f)
    126.                     {
    127.                         sum += GRABXYPIXEL(range, 0);
    128.                         sum += GRABXYPIXEL(-range, 0);
    129.                         sum += GRABXYPIXEL(0, range);
    130.                         sum += GRABXYPIXEL(0, -range);
    131.                         measurments += 4;
    132.                    }
    133.                     return sum / measurments * i.color;
    134.                 }
    135.                 ENDCG
    136.             }
    137.         }
    138.     }
    139. }
     
  41. alkaitagi

    alkaitagi

    Joined:
    Dec 8, 2016
    Posts:
    87
    Hi, tried your shader, but it does not produce any blur.
     
  42. alkaitagi

    alkaitagi

    Joined:
    Dec 8, 2016
    Posts:
    87
    To be more precise, it produce very very low amount of blur when image color's alpha is less than 230
     
  43. Democide

    Democide

    Joined:
    Jan 29, 2013
    Posts:
    315
    Question on this topic - does anyone notice a sort of stripe error when you rotate the UI object around X or Y? I'm looking at the shader and trying to fix it but so far I haven't had any luck.
     
  44. Orr10c

    Orr10c

    Joined:
    Sep 11, 2016
    Posts:
    45
    Yes, an issue im dealing with as well with this shader, anyone has a fix to that?
     
  45. JohannesMP

    JohannesMP

    Joined:
    Nov 4, 2016
    Posts:
    21
    After trying a handful of shaders from this topic and other online resources, I was unable to find one that supported all of these requirements:
    • Ability to mask the blur effect with the image's alpha (ignoring tint so a user can use the image tint to modify or hide or show the image without affecting the blur)
    • Ability to independently tint/change alpha of the blurred background itself.
    • One material usable on many UI elements in the same scene (no need to multiple materials or a manager component).
    • Specifically if two masked blur images with the same material overlap, several solutions resulted in issues like this:
    • Ability to place a blur image as a child of a Mask object and have it masked correctly
    • Ability to have the blur image object also have a Mask component and have it mask its childrens correctly
    After a bit of tweaking I was able to support all but the last requirement (I'm not familiar enough with Stencils there):


    For good measure I also added 'overlay' blend logic (like the photoshop blend mode) that lets you tint the blurred area both to lighten and darken.

    You can find the source code here (one shader and one .cginc file for convenience): https://gist.github.com/JohannesMP/7d62f282705169a2855a0aac315ff381

    Please note that optimizing the convolution logic was not my priority, so it's just an inefficient box blur using for loops in a Y and an X pass. Feel free to modify it to your optimized Gaussian implementation of choice.
     
    Last edited: Oct 3, 2018
    Fenikkel, xenofusion, Ga2Z and 29 others like this.
  46. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    JohannesMP deserves 1000 likes for this
     
    UnderscoreA likes this.
  47. Krstn

    Krstn

    Joined:
    Dec 30, 2012
    Posts:
    27
    It looks amazing, but I think i am missing something. Are there any other steps necessary to make this work?
    I have configured it more or less exactly as in your gif, but the only effect i can get is transparency.

    upload_2018-10-20_22-2-44.png

    I'll be really grateful for any tips on this.

    EDIT:
    When i edit the effect un the Scene view, I can actually see the blur, but when i switch to Game, it's gone. I can see it in game only when using the Screen Space - Overlay render mode, but I have to use Screen Space - camera.Is there any way to make it work with this mode?
     
    Last edited: Oct 21, 2018
  48. Flindt

    Flindt

    Joined:
    Dec 28, 2016
    Posts:
    78
  49. JohannesMP

    JohannesMP

    Joined:
    Nov 4, 2016
    Posts:
    21
    I hope I didn't oversell it, I definitely haven't rigorously unit tested it with all kinds of configurations, so your mileage may vary. I'm also not generally a graphics programmer by trade, more tools-oriented.

    With regards to HDR, I'm not sure if this is what you mean, but on the actual project where I used this I accounted for linear/gamma colors using the UNITY_COLORSPACE_GAMMA shader define.

    Code (CSharp):
    1. #ifdef UNITY_COLORSPACE_GAMMA
    2.         #define GAMMA_CONVERT_COLOR(color) pow(color, 1.0/2.2)
    3. #else
    4.         #define GAMMA_CONVERT_COLOR(color) color
    5. #endif      
    I am unsure if this is the "correct" way to handle that, but it made my colors work (or at least look 'good enough') when I switched the project (Unity 2017.1.2) between gamma and linear color space. Hope that helps.
     
  50. oANDRYo

    oANDRYo

    Joined:
    Nov 27, 2017
    Posts:
    6
    Does it work on iOS as well?