|
| 1 | +Shader "ReactUnity/BackdropFilter" |
| 2 | +{ |
| 3 | + Properties { |
| 4 | + _MainTex ("Tint Color (RGB)", 2D) = "white" {} |
| 5 | + _Color ("Main Color", Color) = (1,1,1,1) |
| 6 | + |
| 7 | + _Blur ("Blur Size", Range(0.0, 10.0)) = 0.0 |
| 8 | + _Brightness ("Brightness", Range(0.0, 2.0)) = 1.0 |
| 9 | + _Contrast ("Contrast", Range(0.0, 2.0)) = 1.0 |
| 10 | + _Grayscale ("Grayscale", Range(0.0, 1.0)) = 0.0 |
| 11 | + _HueRotate ("Hue Rotate", Range(-180, 180)) = 0.0 |
| 12 | + _Invert ("Invert", Range(0.0, 1.0)) = 0.0 |
| 13 | + _Opacity ("Opacity", Range(0.0, 1.0)) = 1.0 |
| 14 | + _Saturate ("Saturate", Range(0.0, 2.0)) = 1.0 |
| 15 | + _Grain ("Grain", Range(0.0, 1.0)) = 0.0 |
| 16 | + _Pixelate ("Pixelate", Range(0.0, 100.0)) = 0.0 |
| 17 | + _Sepia ("Sepia", Range(0.0, 1.0)) = 0.0 |
| 18 | + |
| 19 | + |
| 20 | + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 |
| 21 | + _Stencil("Stencil ID", Float) = 0 |
| 22 | + [Enum(UnityEngine.Rendering.StencilOp)] _StencilOp("Stencil Operation", Float) = 0 |
| 23 | + _StencilWriteMask("Stencil Write Mask", Float) = 255 |
| 24 | + _StencilReadMask("Stencil Read Mask", Float) = 255 |
| 25 | + _ColorMask("Color Mask", Float) = 15 |
| 26 | + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0 |
| 27 | + [Toggle(UNITY_UI_CLIP_RECT)] _UseUIClipRect("Use Clip Rect", Float) = 1 |
| 28 | + } |
| 29 | + |
| 30 | + Category { |
| 31 | + Tags { |
| 32 | + "Queue" = "Transparent" |
| 33 | + "IgnoreProjector" = "True" |
| 34 | + "RenderType" = "Transparent" |
| 35 | + "PreviewType" = "Plane" |
| 36 | + "CanUseSpriteAtlas" = "True" |
| 37 | + } |
| 38 | + |
| 39 | + Stencil { |
| 40 | + Ref[_Stencil] |
| 41 | + Comp[_StencilComp] |
| 42 | + Pass[_StencilOp] |
| 43 | + ReadMask[_StencilReadMask] |
| 44 | + WriteMask[_StencilWriteMask] |
| 45 | + } |
| 46 | + Cull Off |
| 47 | + Lighting Off |
| 48 | + ZTest[unity_GUIZTestMode] |
| 49 | + ColorMask[_ColorMask] |
| 50 | + |
| 51 | + Blend SrcAlpha OneMinusSrcAlpha |
| 52 | + ZWrite Off |
| 53 | + |
| 54 | + SubShader { |
| 55 | + GrabPass { } |
| 56 | + |
| 57 | + Pass { |
| 58 | + CGPROGRAM |
| 59 | + #pragma vertex vert |
| 60 | + #pragma fragment frag |
| 61 | + #pragma target 2.0 |
| 62 | + #pragma shader_feature_local _SPECULARHIGHLIGHTS_OFF |
| 63 | + #pragma shader_feature_local _GLOSSYREFLECTIONS_OFF |
| 64 | + #pragma fragmentoption ARB_precision_hint_fastest |
| 65 | + #include "UnityCG.cginc" |
| 66 | + #include "ShaderSetup.cginc" |
| 67 | + |
| 68 | + float _Blur; |
| 69 | + sampler2D _GrabTexture; |
| 70 | + float4 _GrabTexture_TexelSize; |
| 71 | + |
| 72 | + float4 frag( v2f i ) : COLOR { |
| 73 | + if(_Blur == 0) return tex2D(_GrabTexture, i.uv); |
| 74 | + |
| 75 | + float3 sum = float3(0,0,0); |
| 76 | + |
| 77 | + #define GRABPIXEL(weight,kernelx) tex2D( _GrabTexture, UNITY_PROJ_COORD(float2(i.uv.x + _GrabTexture_TexelSize.x * kernelx*_Blur, i.uv.y))) * weight |
| 78 | + |
| 79 | + sum += GRABPIXEL(0.05, -4.0); |
| 80 | + sum += GRABPIXEL(0.09, -3.0); |
| 81 | + sum += GRABPIXEL(0.12, -2.0); |
| 82 | + sum += GRABPIXEL(0.15, -1.0); |
| 83 | + sum += GRABPIXEL(0.18, 0.0); |
| 84 | + sum += GRABPIXEL(0.15, +1.0); |
| 85 | + sum += GRABPIXEL(0.12, +2.0); |
| 86 | + sum += GRABPIXEL(0.09, +3.0); |
| 87 | + sum += GRABPIXEL(0.05, +4.0); |
| 88 | + |
| 89 | + return float4(sum, 1); |
| 90 | + } |
| 91 | + ENDCG |
| 92 | + } |
| 93 | + |
| 94 | + GrabPass { } |
| 95 | + |
| 96 | + Pass { |
| 97 | + CGPROGRAM |
| 98 | + #pragma vertex vert |
| 99 | + #pragma fragment frag |
| 100 | + #pragma target 2.0 |
| 101 | + #pragma shader_feature_local _SPECULARHIGHLIGHTS_OFF |
| 102 | + #pragma shader_feature_local _GLOSSYREFLECTIONS_OFF |
| 103 | + #pragma fragmentoption ARB_precision_hint_fastest |
| 104 | + #include "UnityCG.cginc" |
| 105 | + #include "ShaderSetup.cginc" |
| 106 | + |
| 107 | + float _Blur; |
| 108 | + sampler2D _GrabTexture; |
| 109 | + float4 _GrabTexture_TexelSize; |
| 110 | + |
| 111 | + float4 frag( v2f i ) : COLOR { |
| 112 | + if(_Blur == 0) return tex2D(_GrabTexture, i.uv); |
| 113 | + |
| 114 | + float3 sum = float3(0,0,0); |
| 115 | + |
| 116 | + #define GRABPIXEL(weight,kernely) tex2D( _GrabTexture, UNITY_PROJ_COORD(float2(i.uv.x, i.uv.y + _GrabTexture_TexelSize.y * kernely*_Blur))) * weight |
| 117 | + |
| 118 | + sum += GRABPIXEL(0.05, -4.0); |
| 119 | + sum += GRABPIXEL(0.09, -3.0); |
| 120 | + sum += GRABPIXEL(0.12, -2.0); |
| 121 | + sum += GRABPIXEL(0.15, -1.0); |
| 122 | + sum += GRABPIXEL(0.18, 0.0); |
| 123 | + sum += GRABPIXEL(0.15, +1.0); |
| 124 | + sum += GRABPIXEL(0.12, +2.0); |
| 125 | + sum += GRABPIXEL(0.09, +3.0); |
| 126 | + sum += GRABPIXEL(0.05, +4.0); |
| 127 | + |
| 128 | + return float4(sum, 1); |
| 129 | + } |
| 130 | + ENDCG |
| 131 | + } |
| 132 | + |
| 133 | + GrabPass { } |
| 134 | + |
| 135 | + Pass { |
| 136 | + |
| 137 | + CGPROGRAM |
| 138 | + #pragma vertex vert |
| 139 | + #pragma fragment frag |
| 140 | + #pragma target 2.0 |
| 141 | + #pragma shader_feature_local _SPECULARHIGHLIGHTS_OFF |
| 142 | + #pragma shader_feature_local _GLOSSYREFLECTIONS_OFF |
| 143 | + #pragma fragmentoption ARB_precision_hint_fastest |
| 144 | + #include "UnityCG.cginc" |
| 145 | + #include "UnityUI.cginc" |
| 146 | + #include "ShaderSetup.cginc" |
| 147 | + |
| 148 | + #pragma multi_compile_local _ UNITY_UI_CLIP_RECT |
| 149 | + #pragma multi_compile_local _ UNITY_UI_ALPHACLIP |
| 150 | + |
| 151 | + float _Blur; |
| 152 | + float _Brightness; |
| 153 | + float _Contrast; |
| 154 | + float _Grayscale; |
| 155 | + float _HueRotate; |
| 156 | + float _Invert; |
| 157 | + float _Opacity; |
| 158 | + float _Saturate; |
| 159 | + float _Sepia; |
| 160 | + float _Pixelate; |
| 161 | + float _Grain; |
| 162 | + |
| 163 | + float4 _ClipRect; |
| 164 | + sampler2D _GrabTexture; |
| 165 | + float4 _GrabTexture_TexelSize; |
| 166 | + |
| 167 | + // Convert RGB to Grayscale |
| 168 | + float3 rgb2gray(float3 color) |
| 169 | + { |
| 170 | + return dot(color, float3(0.299, 0.587, 0.114)); |
| 171 | + } |
| 172 | + |
| 173 | + // Convert RGB to HSV for Hue and Saturation adjustments |
| 174 | + float3 rgb2hsv(float3 c) |
| 175 | + { |
| 176 | + float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); |
| 177 | + float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); |
| 178 | + float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); |
| 179 | + |
| 180 | + float d = q.x - min(q.w, q.y); |
| 181 | + float e = 1.0e-10; |
| 182 | + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); |
| 183 | + } |
| 184 | + |
| 185 | + // Convert HSV to RGB |
| 186 | + float3 hsv2rgb(float3 c) |
| 187 | + { |
| 188 | + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); |
| 189 | + float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); |
| 190 | + return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); |
| 191 | + } |
| 192 | + |
| 193 | + float rand(float2 co) |
| 194 | + { |
| 195 | + return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453); |
| 196 | + } |
| 197 | + |
| 198 | + float4 frag(v2f i) : SV_Target |
| 199 | + { |
| 200 | + // Grab the texture from behind the current object |
| 201 | + float3 color = tex2D(_GrabTexture, i.uv).rgb; |
| 202 | + |
| 203 | + // Apply pixelate effect |
| 204 | + if (_Pixelate > 0) |
| 205 | + { |
| 206 | + float4 ts = _GrabTexture_TexelSize * _Pixelate; |
| 207 | + float2 uv = round(i.uv / ts.xy) * ts.xy; |
| 208 | + color = tex2D(_GrabTexture, uv).rgb; |
| 209 | + } |
| 210 | + |
| 211 | + // Convert to grayscale if needed |
| 212 | + if (_Grayscale > 0) |
| 213 | + { |
| 214 | + float gray = rgb2gray(color); |
| 215 | + color = lerp(color, float3(gray, gray, gray), _Grayscale); |
| 216 | + } |
| 217 | + |
| 218 | + // Adjust brightness and contrast |
| 219 | + color = color * _Brightness; |
| 220 | + color = (color - 0.5) * _Contrast + 0.5; |
| 221 | + |
| 222 | + // Adjust hue and saturation |
| 223 | + float3 hsv = rgb2hsv(color); |
| 224 | + hsv.x += _HueRotate / 360.0; |
| 225 | + hsv.y *= _Saturate; |
| 226 | + color = hsv2rgb(hsv); |
| 227 | + |
| 228 | + // Apply sepia effect |
| 229 | + if (_Sepia > 0) |
| 230 | + color = lerp(color, float3(dot(color, float3(0.393, 0.769, 0.189)), dot(color, float3(0.349, 0.686, 0.168)), dot(color, float3(0.272, 0.534, 0.131))), _Sepia); |
| 231 | + |
| 232 | + // Invert |
| 233 | + if (_Invert > 0) |
| 234 | + color = lerp(color, 1 - color, _Invert); |
| 235 | + |
| 236 | + // Apply grain |
| 237 | + if (_Grain > 0) |
| 238 | + color += (0.5 - rand(i.uv)) * _Grain; |
| 239 | + |
| 240 | + float4 res = float4(color, _Opacity); |
| 241 | + |
| 242 | + |
| 243 | + #ifdef UNITY_UI_CLIP_RECT |
| 244 | + res.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect); |
| 245 | + #endif |
| 246 | + |
| 247 | + #ifdef UNITY_UI_ALPHACLIP |
| 248 | + clip(res.a - 0.001); |
| 249 | + #endif |
| 250 | + |
| 251 | + return res; |
| 252 | + } |
| 253 | + |
| 254 | + ENDCG |
| 255 | + } |
| 256 | + } |
| 257 | + } |
| 258 | +} |
0 commit comments