Skip to content

Instantly share code, notes, and snippets.

@jhocking
Created February 9, 2021 16:17
Show Gist options
  • Select an option

  • Save jhocking/9de4197daf84698a60e51c67695d2be3 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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
Copy Markdown

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

@jhocking
Copy link
Copy Markdown
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
Copy Markdown

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