首页 > 其他分享 >后处理 - 高斯模糊

后处理 - 高斯模糊

时间:2024-03-29 22:12:20浏览次数:19  
标签:Material RenderTexture MainTex 模糊 half2 后处理 source BlurOffset 高斯

原理

采样5x5范围的像素(即25个像素),然后按中间往外减少的权重值,计算出最终颜色值。

 

效果

 

c#代码

using UnityEngine;

public class GaussianBlurEff : MonoBehaviour
{
    public Shader m_Shader;
    public Material m_Material;

    [Range(-3, 3)]
    public float m_BlurOffset = 1;

    public bool m_DoubleBlur; //是否启用双重模糊

    private int m_SrcRTWidth;
    private int m_SrcRTHeight;

    private RenderTexture m_RTHalfSize; //一半大小
    private RenderTexture m_RTQuarterSize; //1/4大小

    void Start()
    {
        if (false == SystemInfo.supportsImageEffects)
        {
            Debug.LogWarning("This platform does not support image effects or render textures.");
            this.enabled = false;
            return;
        }
        InitMaterial(ref m_Shader, ref m_Material);
        if (null != m_Material)
            m_Material.SetFloat("_BlurOffset", m_BlurOffset);
    }

    private static void InitMaterial(ref Shader s, ref Material mat)
    {
        if (null == mat)
        {
            if (null != s && s.isSupported)
            {
                mat = new Material(s);
                mat.hideFlags = HideFlags.DontSave;
            }
        }
        else if (null != s && mat.shader != s)
        {
            if (s.isSupported) //优先shader
            {
                mat = new Material(s);
                mat.hideFlags = HideFlags.DontSave;
            }
            else
            {
                mat = null;
            }
        }
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (null == m_Material)
        {
            Graphics.Blit(source, destination);
        }
        else
        {
#if UNITY_EDITOR
            m_Material.SetFloat("_BlurOffset", m_BlurOffset);
#endif
            if (m_DoubleBlur)
                DoubleBlur(source, destination);
            else
                Graphics.Blit(source, destination, m_Material, 0);
        }
    }

    private void DoubleBlur(RenderTexture source, RenderTexture destination)
    {
        if (m_SrcRTWidth != source.width || m_SrcRTHeight != source.height)
        {
            m_SrcRTWidth = source.width;
            m_SrcRTHeight = source.height;
            m_RTHalfSize = RenderTexture.GetTemporary((int)(m_SrcRTWidth * 0.5f), (int)(m_SrcRTHeight * 0.5f));
            m_RTQuarterSize = RenderTexture.GetTemporary((int)(m_SrcRTWidth * 0.25f), (int)(m_SrcRTHeight * 0.25f));
        }

        //降采样
        Graphics.Blit(source, m_RTHalfSize, m_Material, 0);
        Graphics.Blit(m_RTHalfSize, m_RTQuarterSize, m_Material, 1);

        //升采样
        Graphics.Blit(m_RTQuarterSize, m_RTHalfSize, m_Material, 0);
        Graphics.Blit(m_RTHalfSize, destination, m_Material, 1);
    }

    void OnDestroy()
    {
        if (null != m_RTHalfSize)
        {
            RenderTexture.ReleaseTemporary(m_RTHalfSize);
            RenderTexture.ReleaseTemporary(m_RTQuarterSize);
            m_RTHalfSize = null;
            m_RTQuarterSize = null;
        }
    }

}

 

shader

Shader "My/PostEff/GaussianBlur"
{
	CGINCLUDE
	#include "UnityCG.cginc"

	sampler2D _MainTex;
	float4 _MainTex_TexelSize; //贴图大小信息, 1/width, 1/height, width, height
	float _BlurOffset;

	//高斯模糊横向
	half4 frag_HorizontalBlur(v2f_img i) : SV_Target
	{
		half2 uv1 = i.uv + _MainTex_TexelSize.xy* half2(1, 0)*_BlurOffset * -2.0; //-2/width * _BlurOffset
		half2 uv2 = i.uv + _MainTex_TexelSize.xy* half2(1, 0)*_BlurOffset * -1.0; //-1/width * _BlurOffset
		half2 uv3 = i.uv;
		half2 uv4 = i.uv + _MainTex_TexelSize.xy* half2(1, 0)*_BlurOffset * 1.0; //1/width * _BlurOffset
		half2 uv5 = i.uv + _MainTex_TexelSize.xy* half2(1, 0)*_BlurOffset * 2.0; //2/width * _BlurOffset

		half4 s = 0;
		//权重从中间外往减少
		s += tex2D(_MainTex, uv1) * 0.05;
		s += tex2D(_MainTex, uv2) * 0.25;
		s += tex2D(_MainTex, uv3) * 0.40; //中间权重
		s += tex2D(_MainTex, uv4) * 0.25;
		s += tex2D(_MainTex, uv5) * 0.05;
		return s;
	}

	//高斯模糊纵向
	half4 frag_VerticalBlur(v2f_img i) : SV_Target
	{
		half2 uv1 = i.uv + _MainTex_TexelSize.xy* half2(0, 1)*_BlurOffset * -2.0; //-2/height * _BlurOffset
		half2 uv2 = i.uv + _MainTex_TexelSize.xy* half2(0, 1)*_BlurOffset * -1.0; //-1/height * _BlurOffset
		half2 uv3 = i.uv;
		half2 uv4 = i.uv + _MainTex_TexelSize.xy* half2(0, 1)*_BlurOffset * 1.0; //1/height * _BlurOffset
		half2 uv5 = i.uv + _MainTex_TexelSize.xy* half2(0, 1)*_BlurOffset * 2.0; //2/height * _BlurOffset

		half4 s = 0;
		//权重从中间外往减少
		s += tex2D(_MainTex, uv1) * 0.05;
		s += tex2D(_MainTex, uv2) * 0.25;
		s += tex2D(_MainTex, uv3) * 0.40; //中间权重
		s += tex2D(_MainTex, uv4) * 0.25;
		s += tex2D(_MainTex, uv5) * 0.05;
		return s;
	}
	ENDCG

	Properties
	{
		_MainTex("Texture", 2D) = "white" {} //主贴图
		_BlurOffset("BlurOffset", Float) = 1
	}
	SubShader
	{
		Cull Off //剔除关闭
		ZWrite Off //写入深度buff关闭
		ZTest Always //深度测试启用

		Pass //Pass0
		{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag_HorizontalBlur

			ENDCG
		}

		Pass //Pass1
		{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag_VerticalBlur

			ENDCG
		}

	}

}

 

参考

Unity自定义后处理——模糊效果_unity图片模糊效果-CSDN博客

 

标签:Material,RenderTexture,MainTex,模糊,half2,后处理,source,BlurOffset,高斯
From: https://www.cnblogs.com/sailJs/p/18102276

相关文章

  • MySQL单表操作学习DDL_DML_DQL语句,以及模糊查询
    1.DDL语句CREATETABLE`student`(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'学号',`creatDate`datetimeDEFAULTNULL,`userName`varchar(20)DEFAULTNULL,`pwd`varchar(36)DEFAULTNULL,`phone`varchar(11)DEFAULTNULL,`age`tinyi......
  • EM求解高斯混合模型GMM 原理+公式推导+代码
    1简介EM(Expectation-Maximum)算法也称期望最大化算法,它是为了解决在方程无法获得解析解的情况下,通过迭代给出数值解。核心:EM算法是一种迭代算法,用于含有隐变量的概率模型参数的极大似然估计(因此在往下面看之前,我希望你对贝叶斯的基本理论有所了解)2极大似然估计(1)问题背......
  • 后处理 - 均值模糊
    原理就是取自身以及该像素周围的8个像素的颜色值相加,然后除9取个平均值,得到最终颜色值 效果因为模糊后会出现一些方形的像素效果,模糊效果不是很平均,所以均值模糊也叫做盒状模糊。 c#代码usingUnityEngine;publicclassBoxBlurEff:MonoBehaviour{publicSha......
  • 数据库的创建与模糊查询
    数据库名称可以为【schoolDB】,字符集【utf8】,排列规则【utf8_general_ci】。创建表CREATETABLE`student`(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'学号',`createDate`datetimeDEFAULTNULL,`userName`varchar(20)DEFAULTNULL,`pwd`varchar(36)......
  • 高斯混合模型(GMM)和EM算法 —— python实现
    一、EM算法EM算法是一种迭代算法,用于含有隐含变量的概率模型参数的极大似然估计。设Y为观测随机变量的数据,Z为隐藏的随机变量数据,Y和Z一起称为完全数据。观测数据的似然函数为:模型参数θ的极大似然估计为:这个问题只有通过迭代求解,下面给出EM算法的迭代求解过程:step1、选择......
  • 后处理 - 色调映射
    就是将颜色值通过映射公式得到另一种颜色值,比如:将颜色值*0.8也算是映射公式但这边介绍的映射公式可以得到一种电影校色的效果,至于原理,一般都是经验公式。 效果 c#代码usingUnityEngine;publicclassTonemappingEff:MonoBehaviour{publicShaderm_Shader;......
  • 后处理 - 亮度,饱和度,对比度
    效果 c#代码usingUnityEngine;publicclassMyBrightnessSaturationAndContrast:MonoBehaviour{publicShaderm_Shader;publicMaterialm_Material;[Range(0.0f,3.0f)]publicfloatm_brightness=1.0f;[Range(0.0f,3.0f)]publ......
  • 面试题:在百万keys的Redis里面,如何模糊查找某个key.
    面试题:在百万keys的Redis里面,如何模糊查找某个key.在百万级别的Redis数据库中,进行模糊查找某个key时,需要注意查询效率和对Redis服务器性能的影响。以下是一些建议和方法:1.使用SCAN命令代替KEYS由于KEYS命令在大规模数据集上执行时会阻塞Redis服务器,并可能导致严重......
  • 高斯消元学习笔记
    注:此篇一直在讲高斯-约旦消元法。https://oi-wiki.org/math/numerical/gauss/相信大家都读过上面那个wiki。大家其实都看得挺懵的对吧。今天我就来教一下大家高斯消元。技术指导:milk,周百万,TB\(\LaTeX\)指导:不是你觉得这文章\(\LaTeX\)很好吗?所以没有指导。首先小学知识......
  • 基于Simulink的模糊PID控制
    基于Simulink的模糊PID控制Simulink是一个模块图环境,用于多域仿真以及基于模型的设计。它支持系统级设计、仿真、自动代码生成以及嵌入式系统的连续测试和验证。Simulink提供图形编辑器、可自定义的模块库以及求解器,能够进行动态系统建模和仿真。模糊控制论是以模糊集......