Changelog
// format follows Keep a Changelog
v1.0.0
2026-06-25
Added
Blur Algorithms
Six blur algorithms: Dual Kawase, Gaussian Separable, Tent/Hex, Poisson Disk, Custom Kawase, Radial — all implemented with URP 17+ native RenderGraph API.
Resolution-independent blur scaling — continuous parameters (
blurOffset, gaussianRadius, radialRadius) scale with screen width relative to 1920 px baseline; discrete parameters (iterations, taps, radialTaps) do not scale.Architecture
ScriptableRendererFeature + ScriptableRenderPass architecture supporting up to 16 independent BlurProfile slots simultaneously, each independently configured via a BlurProfile ScriptableObject asset.IBlurConsumer interface — common contract shared by BlurImage and BlurObject, allowing the Renderer Feature to manage both without distinguishing between them.Two capture modes:
CaptureMode.WithoutPostProcessing (before transparents — compatible with all Canvas modes) and CaptureMode.WithPostProcessing (after post-processing — Screen Space Overlay only); each mode is an independent pass-chain, paying GPU cost only when at least one consumer requests that branch.Profile isolation — each profile's textures are fully independent; no configuration can cause one profile's blur to contaminate another's output.
Active state and capture branches for each profile are fully recomputed every frame — the system self-corrects after domain reloads and Play-mode-exit without manual intervention.
slotIndex on BlurProfile — 1-based index (1–16) assigned automatically whenever the profiles list changes; consumers read it directly to identify which blur output to sample.Components
BlurImage component — attaches a BlurProfile's blur output to any UI Graphic; owns a fully private Material instance; appearance fields (frost tint, brightness, desaturation, vignette, normal map, tiling, offset) synced lazily via dirty flag; MarkDirty() for script-driven updates.BlurImage.FadeIn(float duration) / FadeOut(float duration) — coroutine-based built-in fade API that animates profile.intensity from its current value to full or zero over the given duration. Uses Time.unscaledDeltaTime so fades work when Time.timeScale = 0. Both methods reverse smoothly if called mid-animation.BlurObject component — attaches a BlurProfile's blur output to any 3D MeshRenderer using the WorldObject shader; always captures WithoutPostProcessing (self-sampling guard); supports frost tint, brightness, desaturation, IOR refraction, normal map distortion, albedo overlay, and MarkDirty().Blur.RegisterImage / UnregisterImage / RegisterObject / UnregisterObject — explicit consumer registration; consumers self-register in OnEnable / Update and self-unregister in OnDisable.Blur.GetPresetUserCount(BlurProfile) — returns how many currently enabled, visible consumers reference a given profile.Blur.CountSceneConsumers(BlurProfile) / FindSceneConsumerObjects(BlurProfile) — Editor-only utilities using FindObjectsByType with FindObjectsInactive.Include; used by Inspectors for "Show All" scene highlight.Runtime API
BlurProfile.intensity — runtime float (0–1) that scales all blur-strength parameters each frame without modifying serialized values. Scaled: blurOffset, gaussianRadius, radialRadius, iterations, downsample. Not scaled: blurMethod, taps, radialTaps, useIGNRotation. Inspector shows a live slider in both Edit mode and Play mode.BlurProfile.SetIntensity(float) / GetIntensity() — typed accessor pair for intensity. Per-profile; multiple BlurImages sharing a profile are affected simultaneously.BlurProfile.updateMode (BlurUpdateMode: EveryFrame, Throttled) — controls how often the blur pass chain re-runs. Skipped frames reuse the last persistent RTHandle at zero added cost.BlurProfile.throttleFps (int 0–120) — maximum blur updates per second in Throttled mode. 0 = freeze: blurs once on activation and holds that frame until the profile goes inactive; re-captures automatically on reopen.Shaders
UI_Blur_Universal shader for UI panels — frosted glass tint, brightness, desaturation, vignette edge darkening, and normal-map glass distortion; three normal mapping modes: Standard Tile, Local Fixed Scale, Screen Space Fix; up to 16 profile slots × 2 branches via shader_feature_local keywords.WorldObject shader for 3D world-space glass meshes — IOR refraction via refract() with normal map support; samples _BlurredBackground_WorldObjects; same 16-slot keyword system.Editor Tooling
BlurSetupWizard — auto-opens once per project on first import; scans all UniversalRendererData and Renderer2DData assets; adds the Blur Renderer Feature via SerializedObject to keep m_RendererFeatureMap in sync; auto-assigns the bundled UI-Overlay.asset default profile on feature add. Re-openable via Tools → URPUIBlurPro → Setup Wizard.BlurProfileSync (AssetPostprocessor) — keeps all BlurProfile sub-assets in sync with every Blur Renderer Feature whenever profile assets are created or deleted; assigns stable slotIndex values (1–16, over-limit profiles get slot 0); notifies live consumers to reapply keywords via EditorApplication.delayCall.Orphaned sub-asset cleanup — detects and removes
BlurProfile sub-assets left behind when a Blur Renderer Feature is removed; available automatically on asset change and manually via Tools → URPUIBlurPro → Clean Up Orphaned Profiles.BlurProfileEditor — per-method field visibility, algorithm info box with performance cost indicator, runtime intensity slider (Edit mode and Play mode), Update Mode controls with per-mode guidance, and scene consumer list.BlurImageEditor — live appearance preview, profile user count, inline intensity slider, and Fade API buttons (Play mode).BlurObjectEditor — frosted glass appearance preview, profile user count, Update Mode controls, and "Show All Users" scene highlight.Assets
Included materials:
UI_Blur_Universal.mat (UI panels) and Blur_WorldSurface.mat (3D world meshes) — pre-configured, no wizard generation needed.Interactive Demo Scene (
Samples~) comparing all six blur methods with live runtime parameter controls.Fixed
Blur appeared stretched horizontally in Gaussian Separable and Tent/Hex modes at certain resolutions.
Blur darkened at high iteration counts in Dual Kawase, Tent/Hex, and Gaussian modes — affected result appeared darker than the original scene.
Screen UV drift at 4K resolution — blur panels shifted or misaligned at resolutions above 1080p.
Blur texture contamination between profiles — at certain configurations, one profile's blur could appear inside another profile's panel.
Pass name collisions when multiple profiles used the same algorithm — could cause incorrect render graph execution order.
Grey panel flash in Edit mode — panels briefly showed a solid grey color when the canvas re-rendered in the Editor.
Null profile showing another profile's blur — a
BlurImage with no profile assigned could display blur output intended for a different panel.Material instance leak on BlurObject — a new material instance was created every frame instead of being reused, causing memory to grow over time.
Blur panel showed wrong content after domain reload — blur output could be missing or incorrect after entering Play mode following a script recompile.
Dark fringe at panel edges with normal map at high bump strength — the blur area is now automatically extended to cover the full distortion range.