UI blur for URP
A real-time Kawase dual-filter blur for Unity UI, rendered as a URP Renderer Feature.
on this page
com.bluecadet.uiblur renders a screen-space blur to a global texture (_UIBlurTexture by default) that any UI shader can sample. It integrates with the Universal Render Pipeline through UIBlurRenderFeature, added to a URP Renderer asset. The blur is a Kawase dual filter, implemented across KawaseDualFilter, UIBlurRenderPass, and UIBlurRenderFeature (namespace Bluecadet.UIBlur).
Requirements
- Unity 6000.3+
- Universal Render Pipeline (URP)
package.json declares no dependency on URP. If URP isn’t installed in the consuming project, this package won’t compile.
Install
OpenUPM is the recommended path:
openupm add com.bluecadet.uiblurThe scoped registry (https://package.openupm.com, scope com.bluecadet) only needs adding once per project.
To install from a Git URL instead, point at the release tag, which follows the com.bluecadet.uiblur@<version> format:
{
"dependencies": {
"com.bluecadet.uiblur": "https://github.com/bluecadet/unity-packages.git?path=Packages/com.bluecadet.uiblur#com.bluecadet.uiblur@<version>"
}
}Pick a version from Releases — every released tag is listed there. The openupm add form above always takes the latest.
Setup
- Select your URP Renderer asset (e.g.
UniversalRenderer). - Click Add Renderer Feature.
- Select UI Blur Render Feature.
- Configure the settings below.
Settings
| Field | Range | Default | Description |
|---|---|---|---|
blurScale | 0–256 | 4 | Blur intensity. Higher values produce stronger blur. |
renderTextureName | string | _UIBlurTexture | Name of the global render texture that UI shaders sample. |
resolutionScale | 0.25–1.0 | 0.5 | Render resolution multiplier. Lower values improve performance. UIBlurRenderPass.Setup re-clamps this to 0.1–1 internally. |
renderPassEvent | enum | AfterRenderingTransparents | When the render feature injects its pass. |
There’s no “Blur Passes” inspector setting. Pass count is computed at render time from blurScale via KawaseDualFilter.ComputeBlurParams, capped internally at 6 passes — it isn’t user-configurable.
UIBlurRenderFeature also exposes a public BlurScale float property, a passthrough to the underlying blurScale field, for adjusting blur strength from script. renderTextureName and resolutionScale have no equivalent public wrapper.
Sample in a UI shader
sampler2D _UIBlurTexture;
half4 frag(v2f i) : SV_Target {
float2 screenUV = i.screenPos.xy / i.screenPos.w;
half4 blurColor = tex2D(_UIBlurTexture, screenUV);
return blurColor * _Color;
}Algorithm
The blur runs a fixed number of Kawase dual-filter passes, computed from blurScale:
- Downsample: progressively reduce resolution while applying the blur kernel.
- Upsample: progressively increase resolution while blending samples.
This gets most of the visual quality of a Gaussian blur at a fraction of the sample cost. KawaseDualFilter.ComputeBlurParams maps blurScale to a pass count (capped at 6) and a per-pass sample offset; the nested KawaseDualFilter.Resolution struct tracks texel size at each step. The pass records into the Render Graph (RecordRenderGraph, TextureHandle, Blitter.BlitTexture) and is enqueued on the renderer via EnqueuePass.
In the Scene view (CameraType.SceneView), the feature sets the global texture to Texture2D.blackTexture and skips rendering the blur.
Shaders and materials
| Asset | Shader name |
|---|---|
Shaders/KawaseDualFilter.shader | Bluecadet/UIBlur/KawaseDualFilter |
Shaders/UIBlur.shader | Bluecadet/UIBlur/UIBlur |
Materials/UIBlur.mat | Uses Bluecadet/UIBlur/UIBlur. |
Example use cases
- Frosted-glass UI panels
- Background blur behind modals and popups
- Depth-of-field-style UI effects
- Glassmorphism design patterns
HDRP
Building on HDRP instead of URP? See the HDRP package — same blur, integrated as a Custom Pass.