Unity Shader-后处理:简单均值模糊

【Unity ShaderLab】屏幕后处理:模糊 内容 简介 径向模糊 均值模糊 高斯模糊 1. 简介 模糊是一种常见的图像处理手段,也是一种常见的后处理效果,用于降低图片细节层次。对于清晰的图像来说,像素点保存的颜色信息足够准确,图片也就能表现更多的细节。相反,要达到模糊的效果,自然就是将精准的颜色信息“舍弃”掉。 径向模糊 均值模糊 高斯模糊 鬼刀今天更新了吗 2. 径向模糊 ... 阅读详情

一.简介


今天来学习一下后处理中比较常用的一种效果,屏幕模糊效果。模糊效果,在图像处理中经常用到,Photoshop中也有类似的滤镜。我们在游戏中也会经常用到。因为屏幕模糊效果是一些高级后处理效果的基础,比如景深等效果都需要用屏幕模糊效果来实现,所以我们首先看一下屏幕模糊效果,然后通过屏幕模糊,进一步学习景深效果与运动模糊效果的实现。

所谓模糊,也就是不清楚,清晰的图片,各个像素之间会有明显的过渡,而如果各个像素之间的差距不是很大,那么图像就会模糊了,极端一点的情况,当一张图片所有的像素之间颜色都差不多时,那么这张图片也就是一个纯色的图片了。模糊操作就是让像素间的颜色差距变小,比如A点是红色,A点周围的点是绿色,模糊就像用一把刷子,将A点和周围的点的颜色混合起来,变成最终的颜色。而怎样混合,按照不同的权值进行混合,就可以达到不同的效果了。比如均值模糊,以及著名的高斯模糊。

影响模糊程度的重要因素是模糊半径, 模糊半径越大,模糊程度越大,模糊半径越小,模糊程度越小。那么,模糊半径是什么?所谓模糊半径,也就是我们采样的一个范围,比如我们模糊的半径很小,只是把像素和它周围的一圈定点混合,那么模糊的程度就很小,而如果我们加大模糊半径,极端情况是每个顶点都取了周围所有点,也就是整张图的像素平均值,那么这张图的颜色就会偏向一种颜色。

二.均值模糊


最简单的,我们看一下简单的模糊,直接用周围像素求和平均,我们混合的最终图像,在某一点的权重仅仅跟模糊半径有关。换句话说,比如模糊半径为1,那么,我们取一个像素点,以及他周围的一圈像素点,一共九个点,直接取平均,那么每个点的权重设置为1/9。这也就是所谓的均值模糊。我们看一下均值模糊的例子。
shader部分:
    Shader "Custom/SimpleBlurEffect"   
    {  
      
        Properties  
        {  
            _MainTex("Base (RGB)", 2D) = "white" {}  
        }  
      
        //通过CGINCLUDE我们可以预定义一些下面在Pass中用到的struct以及函数,  
        //这样在pass中只需要设置渲染状态以及调用函数,shader更加简洁明了  
        CGINCLUDE  
        //cg文件,包含了unity内置的一些cg函数  
        #include "UnityCG.cginc"  
          
        //blur结构体,从blur的vert函数传递到frag函数的参数  
        struct v2f_blur  
        {  
            float4 pos : SV_POSITION; //顶点位置  
            float2 uv  : TEXCOORD0;   //纹理坐标  
            float2 uv1 : TEXCOORD1;  //周围纹理1  
            float2 uv2 : TEXCOORD2;  //周围纹理2  
            float2 uv3 : TEXCOORD3;  //周围纹理3  
            float2 uv4 : TEXCOORD4;  //周围纹理4  
        };  
      
        //用到的变量  
        sampler2D _MainTex;  
        //XX_TexelSize,XX纹理的像素相关大小width,height对应纹理的分辨率,x = 1/width, y = 1/height, z = width, w = height  
        float4 _MainTex_TexelSize;  
        //模糊半径  
        float _BlurRadius;  
      
        //vertex shader  
        v2f_blur vert_blur(appdata_img v)  
        {  
            v2f_blur o;  
            o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
            o.uv = v.texcoord.xy;  
            //计算uv上下左右四个点对于blur半径下的uv坐标  
            o.uv1 = v.texcoord.xy + _BlurRadius * _MainTex_TexelSize * float2( 1,  1);  
            o.uv2 = v.texcoord.xy + _BlurRadius * _MainTex_TexelSize * float2(-1,  1);  
            o.uv3 = v.texcoord.xy + _BlurRadius * _MainTex_TexelSize * float2(-1, -1);  
            o.uv4 = v.texcoord.xy + _BlurRadius * _MainTex_TexelSize * float2( 1, -1);  
      
            return o;  
        }  
      
        //fragment shader  
        fixed4 frag_blur(v2f_blur i) : SV_Target  
        {  
            fixed4 color = fixed4(0,0,0,0);  
      
            color += tex2D(_MainTex, i.uv );  
            color += tex2D(_MainTex, i.uv1);  
            color += tex2D(_MainTex, i.uv2);  
            color += tex2D(_MainTex, i.uv3);  
            color += tex2D(_MainTex, i.uv4);  
              
            //相加取平均,据说shader中乘法比较快  
            return color * 0.2;  
        }  
      
        ENDCG  
      
        //子着色器  
        SubShader  
        {  
            //pass 0: blur effect  
            Pass  
            {  
                ZTest Always  
                Cull Off  
                ZWrite Off  
                Fog{ Mode Off }  
      
                //直接调用vert_blur和frag_blur  
                CGPROGRAM  
                #pragma vertex vert_blur  
                #pragma fragment frag_blur  
                ENDCG  
            }  
        }  
    }  



C#脚本部分:
    using UnityEngine;  
    using System.Collections;  
      
    //编辑状态下也运行  
    [ExecuteInEditMode]  
    //继承自PostEffectBase  
    public class SimpleBlurEffect : PostEffectBase  
    {  
        //模糊半径  
        public float BlurRadius = 1.0f;  
      
        void OnRenderImage(RenderTexture source, RenderTexture destination)  
        {  
            if (_Material)  
            {  
      
                //blur   
                _Material.SetFloat("_BlurRadius", BlurRadius);  
                Graphics.Blit(source, destination, _Material);  
      
            }  
        }  
    }  


注意,此处的PostEffectBase为各种后处理效果的基类,在上一篇文章: Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)中有该类的完整实现,此处不予贴出代码。

效果如下图所示:

原图效果


blurRadius = 1


blurRadius = 5


从上面的模糊效果我们看到,模糊半径越大,模糊的效果越明显。但是!这种效果看起来一点都不舒服,有种近视的赶脚,完全不是平滑的模糊效果,就更不要说进一步的毛玻璃之类的全模糊效果了。


三.均值模糊的改进


既然,一次模糊我们感觉效果不是很尽人意,那么,我们可以尝试迭代模糊,也就是用上一次模糊的输出作为下一次模糊的输入,迭代之后的模糊效果更加明显。先看一下代码,这次,我们的shader代码和上面的一样,没有变动,仅仅是修改了脚本,增加了降分辨率和迭代的两个操作。
    using UnityEngine;  
    using System.Collections;  
      
    //编辑状态下也运行  
    [ExecuteInEditMode]  
    //继承自PostEffectBase  
    public class SimpleBlurEffect : PostEffectBase  
    {  
        //模糊半径  
        public float BlurRadius = 1.0f;  
        //降分辨率  
        public int downSample = 2;  
        //迭代次数  
        public int iteration = 3;  
      
        void OnRenderImage(RenderTexture source, RenderTexture destination)  
        {  
            if (_Material)  
            {  
                //申请RenderTexture,RT的分辨率按照downSample降低  
                RenderTexture rt1 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);  
                RenderTexture rt2 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);  
                
                //直接将原图拷贝到降分辨率的RT上  
                Graphics.Blit(source, rt1);  
      
                //进行迭代,一次迭代进行了两次模糊操作,使用两张RT交叉处理  
                for(int i = 0; i < iteration; i++)  
                {  
                    //用降过分辨率的RT进行模糊处理  
                    _Material.SetFloat("_BlurRadius", BlurRadius);  
                    Graphics.Blit(rt1, rt2, _Material);  
                    Graphics.Blit(rt2, rt1, _Material);  
                }  
      
                //将结果拷贝到目标RT  
                Graphics.Blit(rt1, destination);  
      
                //释放申请的两块RenderBuffer内容  
                RenderTexture.ReleaseTemporary(rt1);  
                RenderTexture.ReleaseTemporary(rt2);  
            }  
        }  
    }  


结果如下:

blurRadius = 1, downSample = 2,  iteration = 3 


blurRadius = 1, downSample = 2, iteration = 5


我们看到,通过迭代以及降低分辨率,我们的模糊效果更加明显了,当迭代次数较大时,会有一种毛玻璃的效果。这里,虽然迭代次数增加了,会耗费更多的性能,但是相应地,我们也降低了分辨率,也减少了采样等计算操作的消耗。

四.RenderTexture介绍


这里,我们通过多次处理,包括降分辨率以及迭代,完成了模糊操作,这里我们需要临时存储上一次处理过的中间输出,所以就需要用渲染中常用的一个概念RenderTexture。

关于RenderTexture,简要介绍一下,我们在渲染场景时,一般都是直接输出到帧缓存,然后输出到屏幕上,然而有的时候,我们并不想直接输出结果,而是需要对这个渲染的结果进行处理,所以,我们就将渲染的结果输出到了一张纹理上,也就是RenderTexture,这也是所有后处理的基础。Unity的RenderTexture还是很好用的,我们不仅仅可以在后处理时使用,还可以通过把摄像机的输出设置到某个RT上,然后用这张RT作为一些类似镜子的物体上,就可以实现镜面效果或者屏幕效果。

不过 RenderTexture还是很耗费资源的,一张大的RenderTexture是屏幕分辨率大小的一张图片,而且是完全不能够压缩的,所以当后处理中RenderTexture用得多时,内存消耗很大,在手机,尤其是大屏手机,内存比较小的情况下, 后处理叠加时很可能会由于内存耗尽而崩溃。所以,我们在使用RenderTexture时需要慎重考虑。如果效果可以接受,我们就可以考虑降低RenderTexture的分辨率,这样,输出的画面效果可能会打一些折扣,但是性能会有很大的提高。而我们的模糊效果,本身降低分辨率就会导致画面比较模糊,所以在这里,我们完全可以放心大胆地降低RT的分辨率,既可以提升效果,又可以大大地减少开销。

这里还有一点,由于OnRenderImage函数每帧在渲染之前都会调用,之前曾经担心会不会每一帧在这里申请RT,然后释放,会不会有很高的GC?经过查找了一些资料,发现Unity这里是进行过处理的,RenderTexture是之前申请好的一块内存区域,我们可以直接使用,而不需要考虑GC的问题,正如这两个函数的名字一样,RenderTexture.GetTemporary和RenderTexture.ReleaseTemporary一样。并且,本人亲测,使用Profile挂了一下这个脚本,发现的确没有GC:



五.总结

本篇文章介绍了模糊的原理以及RenderTexture的概念。给出了一版简单的均值模糊效果,并通过降低分辨率增加迭代次数优化了模糊的表现效果。但是这种模糊效果还是不尽人意,不进行迭代时效果很差,迭代次数大时虽然可以得到一些好的效果,但是相应地,性能耗费也是极大的。所以是时候学习一下更先进的模糊效果了,下一篇就是传说中的《高斯模糊》~哇咔咔


参考文献:

http://blog.youkuaiyun.com/u011047171/article/details/47947397
原文地址:http://blog.youkuaiyun.com/puppet_master/article/details/52547442
unity shader 语法高亮 代码补全 插件 vs 环境下的unity shader语法高亮,代码补全的插件,双击即安装成功,非常好用。各新版本均有支持 立即下载

相关推荐

Unity3D UGUI特效之Image高斯模糊效果

这几天研究了下模糊特效,看了很多文章,其原理就是拿取图片或屏幕数据,然后将周围的元素和目标位置的颜色值进行一个融合计算,然后自己写了一个小小的测试程序。 这个模糊也可以分成两种,一个是自身模糊,一个是从屏幕上取值进行模糊。第一个用于一些小的列表展示,比如未解锁时,是模糊的。第二个是凸显弹框效果的,将背景都模糊掉,自己将这个稍微加强了些可以指定模糊一个位置。 针对移动平台,使用高斯模糊,其实效率不是很高,如果要很好的效果,那么速度卡;如果要速度快,那么效果达不到要求。但是还是在这里记录下,兴许以后能用上。 先说第一个,挂在Image下的模糊特效。 Shader Custom/FrontBlu

Unity中C#向Shader传float数据的优化

今天在看一个案例的时候,看到了SetGlobalFloat(int nameID, float value)这个方法,所以拓展阅读的时候,才有了这篇文章。 参考:https://blog.youkuaiyun.com/ngrandmarch/article/details/46370557 unity中C#向Shader传递参数的方式有以下两种: 1、面向具体Material的SetFloat...

weixin_30235225的博客 1183

MacOS多次踩坑后成功安装Homebrew

来一次性成功安装Homebrew吧 官网提供的安装脚本无法成功安装Homebrew,原因大家都懂的,故采用脚本安装的方式。 下载homebrew的安装脚本brew_install 在Download路径下执行如下脚本 curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install >> brew_install 修改brew_install脚本 修改brew_install脚本。如果你的脚本打开之后是如下

weixin_41847116的博客 1981

解决在VS中编写Unity Shader代码高亮显示、代码补全、自动缩进

此教程为安装VS编写Unity Shader工具插件安装教程 本人刚开始学习Unity Shader,发现得安装了VS上的插件才可以拥有一个比较好的写Shader代码的体验,所以把自己的方法分享出来,希望可以帮到个位 先点击扩展中的管理扩展 在联机右上角搜索栏中搜索Shader,然后下载ShaderLabVS 此插件有代码补全和高亮显示功能,但当我们换行的时候,新的一行没有自动缩进,我们需要再安装另一个插件 在搜索栏搜索SubLime,然后点击下载 两个插件下载完毕后我们点击关闭,然后在关闭VS窗口

weixin_50617270的博客 1万+

从零到一:Gromacs伞形采样的实战避坑指南

本文详细介绍了Gromacs伞形采样技术的实战应用与避坑指南,涵盖核心原理、环境准备、参数设置、数据分析及性能优化等关键环节。特别针对蛋白质-配体结合自由能计算等典型应用场景,提供了弹簧常数设置、采样窗口间距等实用参数建议,帮助研究人员高效完成分子动力学模拟。

weixin_29243279的博客 512

如何利用VS2017创建一个简单的窗口

#如何利用VS2017创建一个简单的窗口 1、新建->Windows桌面向导 2、应用程序类型->桌面应用程序,点击确定 3、点击调试->开始调试 可建立如下图的窗口 4、可以在生成的项目文件的中找到windows17_2的应用程序,打开界面如下: 注:新建空白项目也可以,注意在解决方案资源器中添加.cpp文件,如源.cpp文件,下载代码见博文 ...

weixin_46894139的博客 2914

解决在VS Code中编写Unity Shader代码高亮显示、代码补全、自动缩进

在使用过程中个人感觉VS的代码高亮不是很合理,所以后面用了VS Code,本文就是对解决在VS Code中编写Unity Shader代码高亮显示、代码补全、自动缩进的教程。

weixin_50617270的博客 7958

关于LIO-SAM编译时出现错误 /usr/bin/ld: 找不到 -lBoost::timer

关于LIO-SAM编译时出现错误: 下载LIO-SAM代码 进入LIO-SAM文件夹,通过以下代码编译: mkdir build cd build cmake .. make 报错: /usr/bin/ld: 找不到 -lBoost::timer collect2: error: ld returned 1 exit status CMakeFiles/lio_sam_imuPreintegration.dir/build.make:759: recipe for target 'devel/lib/li

wwtx的博客 3648

Unity 毛玻璃效果(UGUI)—高斯模糊

因为Unity 提供了GrabPass,可以在Shader中很方便的拿到Panel下面的图像,即_GrabTexture。 Shader "Custom/SimpleGrabPassBlur" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _BumpAmt ("Distortion", R

子弹头 2万+

相机图像质量研究(15)常见问题总结:光学结构对成像的影响--暗角

老式相机的暗角往往比较明显,周围一圈能够明显感觉到亮度下降的很多,当然有些电源模仿手持相机的摄影效果,也能看到周围明显的亮度下降。一、

xiaoshixiu的专栏 1123

【Arduino 101】五分钟搞懂PID控制算法

【Arduino 101】五分钟搞懂PID控制算法物料清单尺寸接线 文章目录物料清单尺寸接线 物料清单 Arduino Uno x 1 超声波模块(HC-SR04)x 1 舵机(Tower Pro MG996R)x 1 舵机供电: 5V 稳压管(LM7805) x 1 , 滤波电容 (0.33uF, 0.1uF) x 2, 9V 电池 x 1 滑轨:泡沫板 支架:乐高 滚动物体:胶带(Up试过网球,但是测距模块的表现不理想) 尺寸 接线 ...

机器人工坊 1万+

【Unity Shader】屏幕后处理3.0:均值模糊和高斯模糊

在Unity中尝试了基于屏幕的均值模糊和高斯模糊效果。

qq_41835314的博客 3136

逆向工具:一文讲述 Ghidra 的详细使用

Ghidra是由NSA开源的一款功能强大的逆向工程框架,支持多平台、多架构和多种文件格式分析。本文详细介绍了Ghidra的核心优势、安装配置方法、主界面功能模块,并通过一个CrackMe示例演示了完整的逆向分析流程。文章还讲解了高级功能如交叉引用、控制流图分析、数据类型重建和脚本自动化等,最后提供了常见文件格式的分析技巧。作为IDA Pro的免费替代方案,Ghidra适合个人学习、教学和中小项目使用。(149字)

数据知道的博客 4342

Unity Shader unity文档学习笔记(六):后处理之均值模糊(类似毛玻璃效果)

所谓模糊,也就是不清楚,清晰的图片,各个像素之间会有明显的过渡,而如果各个像素之间的差距不是很大,那么图像就会模糊了,极端一点的情况,当一张图片所有的像素之间颜色都差不多时,那么这张图片也就是一个纯色的图片了。模糊操作就是让像素间的颜色差距变小,比如A点是红色,A点周围的点是绿色,模糊就像用一把刷子,将A点和周围的点的颜色混合起来,变成最终的颜色。而怎样混合,按照不同的权值进行混合,就可以达到不同...

qq_43204246的博客 399

第4.4节:保护轴承与安全系统

飞轮储能系统的保护轴承是磁悬浮失效时的最后安全屏障,其设计需满足非干涉性、高可靠性和有限寿命承载原则。转子跌落过程包括自由下落、碰撞、进动和滑行减速等复杂非线性阶段,产生远超常规工况的冲击载荷。保护轴承需具备极限冲击容量、高温耐受性和抗卡死能力。系统采用多层级安全架构,结合故障诊断与健康管理,通过监测振动、电流等参数实现预测性维护。安全停机序列有序结合主动制动与被动摩擦制动,确保系统在极端工况下的安全。保护轴承类型多样,需根据系统规模与可靠性要求合理选择。

技术工作者 227

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

unity-shader相关

title: unity-shader相关 categories: Unity3d tags: [unity, shader] date: 2017-09-12 10:05:18 comments: false unity shader 相关记录 相关资料 有很多酷炫shader效果的网站 - https://www.shadertoy.com/view/XllcR4 卡通渲染: ...

. 2920

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Unity Shader Post Processing模糊方法

记录一下方便好用,均值模糊,高斯模糊,双重均值。

weixin_46270110的博客 372

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Unity屏幕后处理学习笔记

后处理学习笔记

鹿尘的学习笔记。 467

【unity shader】用数字图像处理的知识写屏幕后处理效果(bloom、高斯模糊、反色、曝光、黑白图像、灰度图像)

用数字图像处理的知识写shader

weixin_43740653的博客 3548

【Unity Shader入门练习】高斯模糊

0x00 序言 本文是《Unity Shader入门精要》读书笔记,最近接触到项目中用到了模糊处理,经过查阅资料,发觉模糊处理是屏幕后处理技术中的一种,就从屏幕后处理技术开始学习。[使用的Unity版本:5.6.1f1] 0x01 效果图 0x02 基本概念 卷积(convolution)操作指的是使用一个卷积核(kernal)对一张图像中的每个像素进行一系列操作。卷积核通常是一个四方

coffeecato的个人博客 1538

Unity Shader-后处理:高斯模糊

一.简介   上一篇文章学习了模糊的原理以及基本的模糊实现,对于清晰和模糊这个定义感觉还是比较说明问题,这里再贴出一下:“清晰的图片,各个像素之间会有明显的过渡,而如果各个像素之间的差距不是很大,那么图像就会模糊了”。鉴于这个定义,我们就可以通过代码来实现模糊的效果。上一篇Unity Shader-后处理:均值模糊中实现了一个基本的均值模糊,也就是将一个像素和其周围的像素取平均值从而进行模糊,...

weixin_34096182的博客 211

Unity Shader实现运动模糊(一) : 摄像机运动产生模糊

运动模糊是个经常会用到的效果,常见的实现步骤是: 对深度纹理进行采样,取得当前片元的深度信息 根据深度信息建立当前片元的NDC空间的坐标curNDCPos 把curNDCPos乘以当前VP矩阵的逆矩阵(即View*Projection)-1,得到当前片元的世界空间坐标WorldPos 把WorldPos乘以上一帧的VP矩阵(即View*Projection),得到上一帧在裁切空间中的位置 la...

博客标题 3406

unity shader屏幕后处理

unity shader屏幕后处理

weixin_46525412的博客 513
上一篇: NEWT的前世今生
下一篇: Unity Shader-后处理:高斯模糊
cbbbc
博客等级 码龄15年 609粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值