Skip to content

Instantly share code, notes, and snippets.

@jhocking
Created February 9, 2021 16:17
Show Gist options
  • Save jhocking/9de4197daf84698a60e51c67695d2be3 to your computer and use it in GitHub Desktop.
Save jhocking/9de4197daf84698a60e51c67695d2be3 to your computer and use it in GitHub Desktop.
Blur the background behind UI
// blur shader from https://stackoverflow.com/questions/29030321/unity3d-blur-the-background-of-a-ui-canvas
// added toggle https://forum.unity.com/threads/shader-properties-no-bool-support.157580/#post-3013337
Shader "Custom/TintedUIBlur" {
Properties {
_Size("Blur", Range(0, 30)) = 3
[HideInInspector] _MainTex("Masking Texture", 2D) = "white" {}
_AdditiveColor("Additive Tint color", Color) = (0, 0, 0, 0)
_MultiplyColor("Multiply Tint color", Color) = (1, 1, 1, 1)
[Toggle(MAKE_DESATURATED)] _MakeDesaturated ("Desaturate", Float) = 0
}
Category {
// We must be transparent, so other objects are drawn before this one.
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
SubShader
{
// Horizontal blur
GrabPass
{
"_HBlur"
}
/*
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
*/
Cull Off
Lighting Off
ZWrite Off
ZTest[unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : POSITION;
float4 uvgrab : TEXCOORD0;
float2 uvmain : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
o.uvgrab.zw = o.vertex.zw;
o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
sampler2D _HBlur;
float4 _HBlur_TexelSize;
float _Size;
float4 _AdditiveColor;
float4 _MultiplyColor;
half4 frag(v2f i) : COLOR
{
half4 sum = half4(0,0,0,0);
#define GRABPIXEL(weight,kernelx) tex2Dproj( _HBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x + _HBlur_TexelSize.x * kernelx * _Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
sum += GRABPIXEL(0.05, -4.0);
sum += GRABPIXEL(0.09, -3.0);
sum += GRABPIXEL(0.12, -2.0);
sum += GRABPIXEL(0.15, -1.0);
sum += GRABPIXEL(0.18, 0.0);
sum += GRABPIXEL(0.15, +1.0);
sum += GRABPIXEL(0.12, +2.0);
sum += GRABPIXEL(0.09, +3.0);
sum += GRABPIXEL(0.05, +4.0);
half4 result = half4(sum.r * _MultiplyColor.r + _AdditiveColor.r,
sum.g * _MultiplyColor.g + _AdditiveColor.g,
sum.b * _MultiplyColor.b + _AdditiveColor.b,
tex2D(_MainTex, i.uvmain).a);
return result;
}
ENDCG
}
// Vertical blur
GrabPass
{
"_VBlur"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma shader_feature MAKE_DESATURATED
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord: TEXCOORD0;
};
struct v2f {
float4 vertex : POSITION;
float4 uvgrab : TEXCOORD0;
float2 uvmain : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata_t v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y * scale) + o.vertex.w) * 0.5;
o.uvgrab.zw = o.vertex.zw;
o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
sampler2D _VBlur;
float4 _VBlur_TexelSize;
float _Size;
float4 _AdditiveColor;
float4 _MultiplyColor;
half4 frag(v2f i) : COLOR
{
half4 sum = half4(0,0,0,0);
#define GRABPIXEL(weight,kernely) tex2Dproj( _VBlur, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _VBlur_TexelSize.y * kernely * _Size, i.uvgrab.z, i.uvgrab.w))) * weight
sum += GRABPIXEL(0.05, -4.0);
sum += GRABPIXEL(0.09, -3.0);
sum += GRABPIXEL(0.12, -2.0);
sum += GRABPIXEL(0.15, -1.0);
sum += GRABPIXEL(0.18, 0.0);
sum += GRABPIXEL(0.15, +1.0);
sum += GRABPIXEL(0.12, +2.0);
sum += GRABPIXEL(0.09, +3.0);
sum += GRABPIXEL(0.05, +4.0);
#ifdef MAKE_DESATURATED
half4 result = half4((sum.r* 0.3 + sum.g* 0.59 + sum.b* 0.11) * _MultiplyColor.r + _AdditiveColor.r,
(sum.r* 0.3 + sum.g* 0.59 + sum.b* 0.11) * _MultiplyColor.g + _AdditiveColor.g,
(sum.r* 0.3 + sum.g* 0.59 + sum.b* 0.11) * _MultiplyColor.b + _AdditiveColor.b,
tex2D(_MainTex, i.uvmain).a);
#else
half4 result = half4(sum.r * _MultiplyColor.r + _AdditiveColor.r,
sum.g * _MultiplyColor.g + _AdditiveColor.g,
sum.b * _MultiplyColor.b + _AdditiveColor.b,
tex2D(_MainTex, i.uvmain).a);
#endif
return result;
}
ENDCG
}
}
}
}
@restush
Copy link

restush commented Jun 5, 2022

Could you add feature reduce canvas blur from Canvas Group alpha? So when alpha is 0.5 the blur power is 50%. Currently when alpha is not 0 (zero) it will always use 100% blur power.

@LastSipahi
Copy link

Does this works on Android ? I'm getting weird scaling results at mobile.

@jhocking
Copy link
Author

I mean, it certainly did work on Android at one point. I haven't actually used this shader in a while though, so perhaps it no longer works right on the latest version. What device are you using?

@LastSipahi
Copy link

Sorry for not giving any details. Shader works on Android Samsung devices but only in Portrait mode. When I turned the device to landscape blur still exists but image shrink to quarter size of screen. I understand this is a flip problem but I can't find a way to adapt your code into turning screen orientation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment