如何在Unity HDRP及VR环境中创建可模糊UI的Blur Shader
在Unity HDRP(2021.3.4)VR环境中实现UI模糊效果的方案
一、直接给UI元素应用的模糊Shader
如果你需要让特定UI元素(比如菜单中的某个面板)本身产生模糊效果,可以使用这个基于Unity默认UI Shader修改的模糊Shader,适配HDRP和VR环境:
Shader "UI/BlurUI" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 // 模糊参数 _BlurSize ("Blur Size", Range(0.0, 10.0)) = 2.0 _BlurIterations ("Blur Iterations", Range(1, 5)) = 2 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask [_ColorMask] Pass { Name "Default" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "UnityUI.cginc" #pragma multi_compile __ UNITY_UI_ALPHACLIP struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; fixed4 _Color; fixed4 _TextureSampleAdd; float4 _ClipRect; float _BlurSize; int _BlurIterations; v2f vert(appdata_t v) { v2f OUT; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); OUT.worldPosition = v.vertex; OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); OUT.texcoord = v.texcoord; OUT.color = v.color * _Color; return OUT; } fixed4 frag(v2f IN) : SV_Target { float2 blurStep = _BlurSize / _ScreenParams.xy; fixed4 col = fixed4(0,0,0,0); // 高斯模糊迭代采样 for(int i = 0; i < _BlurIterations; i++) { float offset = (i - _BlurIterations/2) * blurStep; col += tex2D(_MainTex, IN.texcoord + offset) * (1.0 / _BlurIterations); col += tex2D(_MainTex, IN.texcoord - offset) * (1.0 / _BlurIterations); } col.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); #ifdef UNITY_UI_ALPHACLIP clip (col.a - 0.001); #endif return col + _TextureSampleAdd; } ENDCG } } FallBack "UI/Default" }
使用方式:
- 创建新材质,选择
UI/BlurUI作为Shader。 - 将材质直接拖到目标UI元素(Image、Text等)的
Material字段。 - 在材质面板调整
_BlurSize(模糊范围)和_BlurIterations(模糊精度)参数,直到达到需求效果。
二、VR环境下的全局背景UI模糊(菜单弹出时模糊背景UI)
如果需要实现菜单弹出时,背景UI模糊、菜单自身清晰的效果,可按以下步骤操作:
1. 分层UI设置
- 创建两个Canvas:
- 菜单Canvas:设置
Render Mode为Screen Space - Overlay或绑定到VR主相机的Screen Space - Camera,将Sorting Order设为较高值(如100),确保菜单在最上层。 - 背景UI Canvas:
Sorting Order设为较低值(如0),给该Canvas下所有UI元素应用上面的UI/BlurUI材质。
- 菜单Canvas:设置
2. VR适配配置
- 确保两个Canvas的
Target Display设置为Display 1(Unity会自动处理VR双屏渲染)。 - 若使用
Screen Space - Camera模式,绑定的相机需开启VR Stereo Rendering,并在HDRP相机设置中将Rendering Path设为Forward。
3. 脚本控制模糊开关
用以下脚本实现模糊状态的平滑切换:
using UnityEngine; using UnityEngine.UI; public class UIBlurController : MonoBehaviour { public Material blurMaterial; public float normalBlurSize = 0f; public float blurredBlurSize = 5f; public float transitionSpeed = 2f; private bool _isBlurred; public void ToggleBlur() { _isBlurred = !_isBlurred; } void Update() { float targetSize = _isBlurred ? blurredBlurSize : normalBlurSize; blurMaterial.SetFloat("_BlurSize", Mathf.Lerp(blurMaterial.GetFloat("_BlurSize"), targetSize, Time.deltaTime * transitionSpeed)); } }
使用方式:
- 将脚本挂载到菜单管理器对象上。
- 把背景UI的模糊材质拖到
blurMaterial字段。 - 在菜单的打开/关闭按钮事件中调用
ToggleBlur()方法,即可实现模糊状态切换。
三、HDRP+VR环境注意事项
- 确保HDRP渲染管线资产中,
UI Rendering设置为SRP Batcher Compatible,避免Shader兼容性问题。 - 上述Shader已加入
UNITY_VERTEX_OUTPUT_STEREO宏,自动适配VR双相机的纹理坐标采样。 - 若尝试用额外相机抓取UI渲染纹理,需关闭该相机的
Post Processing,并将Clear Flags设为Depth Only,仅渲染UI层。
内容的提问来源于stack exchange,提问作者Filip5
相关产品推荐
相关产品推荐

