You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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"
}

使用方式:

  1. 创建新材质,选择UI/BlurUI作为Shader。
  2. 将材质直接拖到目标UI元素(Image、Text等)的Material字段。
  3. 在材质面板调整_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材质。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:30:01