首页 > 其他分享 >后处理 - 均值模糊

后处理 - 均值模糊

时间:2024-03-28 23:33:07浏览次数:25  
标签:模糊 RenderTexture Material 均值 Shader 后处理 source BlurOffset null

原理

就是取自身以及该像素周围的8个像素的颜色值相加,然后除9取个平均值,得到最终颜色值

 

效果

因为模糊后会出现一些方形的像素效果,模糊效果不是很平均,所以均值模糊也叫做盒状模糊。

 

c#代码

using UnityEngine;

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

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

    void Start()
    {
        InitMaterial();
    }

    private void InitMaterial()
    {
        if (false == SystemInfo.supportsImageEffects)
        {
            Debug.LogWarning("This platform does not support image effects or render textures.");
            this.enabled = false;
            return;
        }

        if (null == m_Material)
        {
            if (null != m_Shader && m_Shader.isSupported)
            {
                m_Material = new Material(m_Shader);
                m_Material.hideFlags = HideFlags.DontSave;
            }
        }
        else if (null != m_Shader && m_Material.shader != m_Shader)
        {
            if (m_Shader.isSupported) //优先shader
            {
                m_Material = new Material(m_Shader);
                m_Material.hideFlags = HideFlags.DontSave;
            }
            else
            {
                m_Material = null;
            }
        }

        if (null != m_Material)
            m_Material.SetFloat("_BlurOffset", m_BlurOffset);
    }

    private void ReleaseRT(RenderTexture rt)
    {
        if (rt != null) RenderTexture.ReleaseTemporary(rt);
    }

    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
            Graphics.Blit(source, destination, m_Material, 0);
        }
    }
    
}

 

shader

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

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

	float _BlurOffset;

	fixed4 fragBoxBlur(v2f_img i) : SV_Target //片元着色器(逐像素)
	{
		//均值模糊, 这边没有采样9个, 只采样了上下左右4个, 速度更快
		float4 colBlur = 0;
		// (1/width, 1/height, -1/width, -1/height)*_BlueOffset
		float4 blurUV = _MainTex_TexelSize.xyxy * float4(1, 1, -1, -1) * _BlurOffset; //控制采样上下左右1个像素还是n个像素
		colBlur += tex2D(_MainTex, i.uv + blurUV.xy);//1,1
		colBlur += tex2D(_MainTex, i.uv + blurUV.xw);//1,-1
		colBlur += tex2D(_MainTex, i.uv + blurUV.zy);//-1,1
		colBlur += tex2D(_MainTex, i.uv + blurUV.zw);//-1,-1

		half4 col = tex2D(_MainTex, i.uv); //获取像素颜色
		col.rgb = colBlur.rgb / 4;
		return col;
	}
	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 fragBoxBlur

			ENDCG
		}

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

			ENDCG
		}
	}

}

 

双重模糊

单次的均值模糊,其实效果并不是很好,这边可以通过双重模糊来优化模糊效果

原理:将图片分辨率降低1倍(降采样),做一次模糊,再降1倍,做一次模糊;

然后再将分辨率升1倍(升采样),做一次模糊,再升1倍,做一次模糊。

 

using UnityEngine;

public class BoxBlurEff : 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()
    {
        InitMaterial();
    }

    private void InitMaterial()
    {
        if (false == SystemInfo.supportsImageEffects)
        {
            Debug.LogWarning("This platform does not support image effects or render textures.");
            this.enabled = false;
            return;
        }

        if (null == m_Material)
        {
            if (null != m_Shader && m_Shader.isSupported)
            {
                m_Material = new Material(m_Shader);
                m_Material.hideFlags = HideFlags.DontSave;
            }
        }
        else if (null != m_Shader && m_Material.shader != m_Shader)
        {
            if (m_Shader.isSupported) //优先shader
            {
                m_Material = new Material(m_Shader);
                m_Material.hideFlags = HideFlags.DontSave;
            }
            else
            {
                m_Material = null;
            }
        }

        if (null != m_Material)
            m_Material.SetFloat("_BlurOffset", m_BlurOffset);
    }

    private void ReleaseRT(RenderTexture rt)
    {
        if (rt != null) RenderTexture.ReleaseTemporary(rt);
    }

    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;
        }
    }

}

效果

 

参考

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

UnityShader实例13:屏幕特效之均值模糊(Box Blur) - yjbjingcha - 博客园 (cnblogs.com)

 

标签:模糊,RenderTexture,Material,均值,Shader,后处理,source,BlurOffset,null
From: https://www.cnblogs.com/sailJs/p/18102055

相关文章

  • 数据库的创建与模糊查询
    数据库名称可以为【schoolDB】,字符集【utf8】,排列规则【utf8_general_ci】。创建表CREATETABLE`student`(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'学号',`createDate`datetimeDEFAULTNULL,`userName`varchar(20)DEFAULTNULL,`pwd`varchar(36)......
  • 后处理 - 色调映射
    就是将颜色值通过映射公式得到另一种颜色值,比如:将颜色值*0.8也算是映射公式但这边介绍的映射公式可以得到一种电影校色的效果,至于原理,一般都是经验公式。 效果 c#代码usingUnityEngine;publicclassTonemappingEff:MonoBehaviour{publicShaderm_Shader;......
  • R语言K-Means(K均值聚类)和层次聚类算法对微博用户特征数据研究
    全文链接:https://tecdat.cn/?p=32955原文出处:拓端数据部落公众号本文就将采用K-means算法和层次聚类对基于用户特征的微博数据帮助客户进行聚类分析。首先对聚类分析作系统介绍。其次对聚类算法进行文献回顾,对其概况、基本思想、算法进行详细介绍,再是通过一个仿真实验具体来强化......
  • 后处理 - 亮度,饱和度,对比度
    效果 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服务器,并可能导致严重......
  • Python——timeit(运行时间平均值计算)
    可以计算其中运行代码所用的平均时间。importtimeitprint(timeit.timeit('a,b=10,20;a1=a;a=b;'))0.015125599999009864使用多重赋值的技巧来交换两个变量,也就是所谓的“迭代解包”它的运行时间是:importtimeitprint(timeit.timeit('a,b=10,20;a,b=b,......
  • 基于Simulink的模糊PID控制
    基于Simulink的模糊PID控制Simulink是一个模块图环境,用于多域仿真以及基于模型的设计。它支持系统级设计、仿真、自动代码生成以及嵌入式系统的连续测试和验证。Simulink提供图形编辑器、可自定义的模块库以及求解器,能够进行动态系统建模和仿真。模糊控制论是以模糊集......
  • 汽车ABS的bangbang控制和模糊PID控制
    1、内容简介略82-可以交流、咨询、答疑2、内容说明   摘要:本文旨在设计一种利用模糊控制理论优化的pid控制器,控制abs系统,达到对滑移率最佳控制范围的要求,所提出的方案采用级联控制架构:设计用于外环中的车轮打滑控制的具有Takagi-Sugeno-Kang模糊推理系统的PID型模糊控......
  • WPF中阴影效果和模糊效果的使用【Xaml】
    原文:https://blog.csdn.net/qq_39847278/article/details/129707074前言WPF中的控件效果主要通过Effect来实现,而Effect有DropShadowEffect(投影效果)和BlurEffect(模糊效果)两个派生类,本文将主要介绍Effect的运用!一、DropShadowEffect1、DropShadowEffect各属性效果图 另外还有......
  • xpath和contains模糊匹配
    来源:https://www.cnblogs.com/kaibindirver/p/12072546.html最近在弄数据爬取,研究了下xpath,也参考了很多文章,这篇总结不错,就直接复制过来了。xpath可以以标签定位,也可以@任意属性:如:以input标签定位:driver.find_element_by_xpath("//input[@id='kw']")如:@type属性:driver.find_......