屏幕后处理-高斯模糊

效果

原图
高斯模糊图

思路

水平与竖直方向上的一维高斯核
使用高斯核,进行卷积计算。可简化为使用两个一维的高斯核,做为采样的权重点,对图像先后进行水平与竖直方向的滤波处理。
采样点为当前像素点的左右各扩展2个单位,上下各扩展2个单位。可自定义后乘以系数,缩放采样的范围。
采样的过程,一般是水平一次,竖直方向一次。可将这个过程进行多次,以达到加强模糊程度的效果。

实现

c#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GaussianBlurTest : PostEffectBaseTest
{

    public Shader gaussianBlurShader;
    private Material gaussianBlurMatrial = null;

    public Material material
    {
        get
        {
            gaussianBlurMatrial = CheckShaderAndCreateMaterial(gaussianBlurShader, gaussianBlurMatrial);
            return gaussianBlurMatrial;
        }
    }

    [Range(0, 4)] public int iterations = 3;

    [Range(0.2f, 3f)] public float blurSpread = 0.6f;

    [Range(1, 8)] public int downSample = 2;

    //使用迭代系数,渲染出更模糊的效果
    private void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (material)
        {
            //降采样
            int rtW = src.width / downSample;
            int rtH = src.height / downSample;
            RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);//得到与屏幕图像大小相同的缓存区
            buffer0.filterMode = FilterMode.Bilinear; //将渲染纹理的滤波模式设置为双线性
            Graphics.Blit(src, buffer0 ); //先渲染一张纹理到缓存
            for (int i = 0; i < iterations; i++)//对画面进行多次模糊渲染
            {
                material.SetFloat("_BlurSize",1.0f+i*blurSpread);//调节模糊的范围大小
                RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);//获取屏幕图像缓存区
                Graphics.Blit(buffer0,buffer1,material,0);//对纹理的竖直方向使用模糊渲染
                RenderTexture.ReleaseTemporary(buffer0);//释放缓冲区
                buffer0 = buffer1;
                
                buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);//获取缓冲区
                Graphics.Blit(buffer0,buffer1,material,1); //对纹理的水平方向使用模糊渲染
                RenderTexture.ReleaseTemporary(buffer0);//释放屏幕缓冲区
                buffer0 = buffer1;
            }
            
            Graphics.Blit(buffer0,dest);//多重渲染后,再计算总结果,渲染出最后的图形
        }
        else
        {
            Graphics.Blit(src,dest);
        }
    }

shader

Shader "Custom/GaussianBlurShader" {
	Properties {
        _MainTex("_MainTex",2D) = "white" {}
        _BlurSize("_BlurSize",Float) = 1.0
	}
	SubShader {
	    CGINCLUDE
	    
	    #include "UnityCG.cginc"
	    sampler2D _MainTex;
	    half4 _MainTex_TexelSize;
	    float _BlurSize;
	    
	    struct v2f {
	        float4 pos : SV_POSITION;
	        half2 uv[5] : TEXCOORD0;
	    
	    };
	    
	    v2f vertexBlurVertiacl( appdata_img v ){ //竖直方向需要处理的点
	        v2f o;
	        o.pos = UnityObjectToClipPos(v.vertex);
	        half2 uv = v.texcoord;
	        计算竖直方向上的需要处理的顶点的位置
	        o.uv[0] = uv;
	        o.uv[1] = uv + float2( 0.0,  _MainTex_TexelSize.y * 1.0f) * _BlurSize;
	        o.uv[2] = uv - float2( 0.0,  _MainTex_TexelSize.y * 1.0f) * _BlurSize;
	        o.uv[3] = uv + float2( 0.0,  _MainTex_TexelSize.y * 2.0f) * _BlurSize;
	        o.uv[4] = uv - float2( 0.0,  _MainTex_TexelSize.y * 2.0f) * _BlurSize;
	        return o;
	    };
	    
        v2f vertexBlurHorizontal( appdata_img v ){
	        v2f o;
	        o.pos = UnityObjectToClipPos(v.vertex);
	        half2 uv = v.texcoord;
	        //计算水平方向上的需要处理的顶点的位置
	        o.uv[0] = uv;
	        o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0f,0.0) * _BlurSize;
	        o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0f,0.0) * _BlurSize;
	        o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0f,0.0) * _BlurSize; 
	        o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.0f,0.0) * _BlurSize;
	        return o;
	    };
	    
	    fixed4 fragBlur(v2f i) : SV_Target{
	        float weight[3] = { 0.4026, 0.2442, 0.0545 };
	        //根据顶点位置乘以权重,再进行采样
            fixed3 sum = tex2D ( _MainTex , i.uv[0]).rgb * weight[0] ;
	        for(int it=1; it <3;it++ ){
	            //根据高斯核算法,得到其他四个点,再乘以改点权重值,再进行采样,并最后求和
	            sum += tex2D( _MainTex, i.uv[it*2-1] ).rgb * weight[it];
	            sum += tex2D(_MainTex, i.uv[it*2]).rgb * weight[it];
	            
	        };
	        return fixed4(sum, 1.0);
	    };
	    
	    
	    
	    
	    ENDCG
	    
	    ZTest Always Cull Off  ZWrite Off
	    Pass{
	        NAME "GAUSSIAN_BLUR_VERTICAL"
	        
	        CGPROGRAM
	        #pragma vertex vertexBlurVertiacl
	        #pragma fragment fragBlur
	        ENDCG
	    }
	    
        Pass{
	        NAME "GAUSSIAN_BLUR_HORIZONTAL"
	        CGPROGRAM
	        #pragma vertex vertexBlurHorizontal
	        #pragma fragment fragBlur
	        ENDCG
	    
	    
	    }
	    
	
	
		
	}
	FallBack Off
}

### 实现 Uni-app 启动页面高斯模糊效果 为了实现在 Uni-app 应用启动时展示带有高斯模糊背景的效果,可以采用如下方法: #### 使用 CSS 进行样式控制 通过自定义 `App.vue` 或者特定页面的样式文件来应用高斯模糊滤镜。这可以通过CSS中的`backdrop-filter`属性完成。 ```css /* 定义全局或者局部样式 */ .launch-background { width: 100%; height: 100vh; background-image: url('/static/your_image.jpg'); /* 替换成实际图片路径 */ backdrop-filter: blur(10px); /* 设置模糊程度 */ } ``` #### 结合 Vue 生命周期钩子函数 利用Vue组件内的生命周期事件,在应用初次加载期间显示具有高斯模糊效果的画面,并在准备就绪之后移除该画面或替换为正常的内容视图。 ```javascript // App.vue or specific page component script section export default { mounted() { setTimeout(() => { // 模拟异步操作后的延迟处理 this.$nextTick(function () { document.querySelector('.launch-background').style.display = 'none'; }); }, 2000); } }; ``` #### 创建启动页模板 创建一个新的HTML结构用于表示启动屏幕,并将其放置于项目根目录下的静态资源文件夹中(如 `/static/index.html`),这样可以在应用程序真正开始之前立即呈现给用户一个视觉上的过渡体验[^1]。 需要注意的是,对于TabBar的行为特性以及优化措施已经由框架本身进行了良好的封装和支持[^2];然而上述提到的技术方案并不直接影响到TabBar的功能实现,而是专注于改善用户体验的一个独立设计思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值