Unity Shader-后处理:高斯模糊
一.简介
二.概念介绍
1.正态分布
2.卷积
如果你每天都到地下去打台球,那么老板每天都要扇你一巴掌,不过当老板打你一巴掌后,你5分钟就消肿了,所以时间长了,你甚至就适应这种生活了……如果有一天,老板忍无可忍,以0.5秒的间隔开始不间断的扇你的过程,这样问题就来了,第一次扇你鼓起来的包还没消肿,第二个巴掌就来了,你脸上的包就可能鼓起来两倍高,老板不断扇你,脉冲不断作用在你脸上,效果不断叠加了,这样这些效果就可以求和了,结果就是你脸上的包的高度随时间变化的一个函数了(注意理解);如果老板再狠一点,频率越来越高,以至于你都辨别不清时间间隔了,那么,求和就变成积分了。可以这样理解,在这个过程中的某一固定的时刻,你的脸上的包的鼓起程度和什么有关呢?和之前每次打你都有关!但是各次的贡献是不一样的,越早打的巴掌,贡献越小,所以这就是说,某一时刻的输出是之前很多次输入乘以各自的衰减系数之后的叠加而形成某一点的输出,然后再把不同时刻的输出点放在一起,形成一个函数,这就是卷积,卷积之后的函数就是你脸上的包的大小随时间变化的函数。本来你的包几分钟就可以消肿,可是如果连续打,几个小时也消不了肿了,这难道不是一种平滑过程么?反映到剑桥大学的公式上,f(a)就是第a个巴掌,g(x-a)就是第a个巴掌在x时刻的作用程度,乘起来再叠加就ok了
三.高斯模糊的实现
Shader "Custom/GaussianBlur"
{Properties{_MainTex("Base (RGB)", 2D) = "white" {}}//通过CGINCLUDE我们可以预定义一些下面在Pass中用到的struct以及函数,//这样在pass中只需要设置渲染状态以及调用函数,shader更加简洁明了CGINCLUDE#include "UnityCG.cginc"//blur结构体,从blur的vert函数传递到frag函数的参数struct v2f_blur{float4 pos : SV_POSITION; //顶点位置float2 uv : TEXCOORD0; //纹理坐标float4 uv01 : TEXCOORD1; //一个vector4存储两个纹理坐标float4 uv23 : TEXCOORD2; //一个vector4存储两个纹理坐标float4 uv45 : TEXCOORD3; //一个vector4存储两个纹理坐标};//shader中用到的参数sampler2D _MainTex;//XX_TexelSize,XX纹理的像素相关大小width,height对应纹理的分辨率,x = 1/width, y = 1/height, z = width, w = heightfloat4 _MainTex_TexelSize;//给一个offset,这个offset可以在外面设置,是我们设置横向和竖向blur的关键参数float4 _offsets;//vertex shaderv2f_blur vert_blur(appdata_img v){v2f_blur o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//uv坐标o.uv = v.texcoord.xy;//计算一个偏移值,offset可能是(0,1,0,0)也可能是(1,0,0,0)这样就表示了横向或者竖向取像素周围的点_offsets *= _MainTex_TexelSize.xyxy;//由于uv可以存储4个值,所以一个uv保存两个vector坐标,_offsets.xyxy * float4(1,1,-1,-1)可能表示(0,1,0-1),表示像素上下两个//坐标,也可能是(1,0,-1,0),表示像素左右两个像素点的坐标,下面*2.0,*3.0同理o.uv01 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1);o.uv23 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 2.0;o.uv45 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 3.0;return o;}//fragment shaderfixed4 frag_blur(v2f_blur i) : SV_Target{fixed4 color = fixed4(0,0,0,0);//将像素本身以及像素左右(或者上下,取决于vertex shader传进来的uv坐标)像素值的加权平均color += 0.4 * tex2D(_MainTex, i.uv);color += 0.15 * tex2D(_MainTex, i.uv01.xy);color += 0.15 * tex2D(_MainTex, i.uv01.zw);color += 0.10 * tex2D(_MainTex, i.uv23.xy);color += 0.10 * tex2D(_MainTex, i.uv23.zw);color += 0.05 * tex2D(_MainTex, i.uv45.xy);color += 0.05 * tex2D(_MainTex, i.uv45.zw);return color;}ENDCG//开始SubShaderSubShader{//开始一个PassPass{//后处理效果一般都是这几个状态ZTest AlwaysCull OffZWrite OffFog{ Mode Off }//使用上面定义的vertex和fragment shaderCGPROGRAM#pragma vertex vert_blur#pragma fragment frag_blurENDCG}}
//后处理效果一般不给fallback,如果不支持,不显示后处理即可
}
using UnityEngine;
using System.Collections;//编辑状态下也运行
[ExecuteInEditMode]
//继承自PostEffectBase
public class GaussianBlur : PostEffectBase
{//模糊半径public float BlurRadius = 1.0f;//降分辨率public int downSample = 2;//迭代次数public int iteration = 1;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);//进行迭代高斯模糊for(int i = 0; i < iteration; i++){//第一次高斯模糊,设置offsets,竖向模糊_Material.SetVector("_offsets", new Vector4(0, BlurRadius, 0, 0));Graphics.Blit(rt1, rt2, _Material);//第二次高斯模糊,设置offsets,横向模糊_Material.SetVector("_offsets", new Vector4(BlurRadius, 0, 0, 0));Graphics.Blit(rt2, rt1, _Material);}//将结果输出Graphics.Blit(rt1, destination);//释放申请的两块RenderBuffer内容RenderTexture.ReleaseTemporary(rt1);RenderTexture.ReleaseTemporary(rt2);}}
}
四.效果展示
五.参考文献
Unity Shader-后处理:高斯模糊相关推荐
- unity shader 后处理实现水墨风格渲染「Low Poly 」变「水墨画 」
#水墨风格渲染 这次学校的比赛打算做一个中国古代背景的游戏,所以尝试做了水墨风格的渲染. 主要按以下四步来实现的效果: 根据色调和饱和度调整饱和度. 对图像进行模糊 水墨风格的物体边缘 物体内画笔笔触 ...
- Unity Shader - 后处理:油画效果
效果图: 效果对比图(一)
- 【Unity Shader】屏幕后处理3.0:均值模糊和高斯模糊
发现之前学习记录的太过详细,导致整理的过程占用太长的时间了,这篇之后博客重要的是掌握实现过程,关于基础的理论会更多的放上别人写得更好的文章. 参考:[Unity Shader编程]之十五 屏幕高斯模糊 ...
- Unity Shader入门学习(5):基础屏幕后处理
1.后处理基类 //屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效. //基类的作用有二:检测平台是否支持后处理效果,及创建一个用于处理渲 ...
- Unity Shader - 模仿RenderImage制作全屏Quad,可以制作自定义后处理的流程
文章目录 先尝试GL类来制作 Shader CSharp 画个三角型 画个全屏的Quad 发现GL没有RenderTarget之类的 使用CommandBuffer来绘制全屏的Quad GL渲染到目标 ...
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
- 【Unity Shader编程】之十五 屏幕高斯模糊(Gaussian Blur)后期特效的实现
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/51871531 作者:毛星云(浅 ...
- (一)unity shader在实际项目中出现的问题————unity的后处理插件景深效果在某些低档机(如三星)无效的解决方案
本专栏主要解决一些移动平台上unity shader效果异常的问题.很多情况下我们发现unity中的shader在PC平台效果正常,但是在移动平台上效果不对,或者部分机型效果不对的问题,尤其是低档老年 ...
- 【Unity Shader】屏幕后处理2.0:实现Sobel边缘检测
边缘检测是描边效果的一种实现方法,关于描边效果其实还有更好的基于深度+法线纹理实现的方法,这里就先以边缘检测为主进行学习. 1 理解卷积 参考:深入理解卷积(卷积核到底要不要翻卷) [深度学习]深度学 ...
- Unity Shader学习笔记(5)基于摄像机深度和法线的后处理描边效果
文章目标 : 主要参考书籍为<Unity Shader入门精要>,本文主要注重于整理,方便后续直接调用. 渲染效果图: 主要相关代码: 摄像机脚本文件: using System.Coll ...
最新文章
- 值得mark的11个开源机器学习项目 .
- linux ssh服务的优化,SSH服务端配置、优化加速、安全防护
- android自定义图标下载,charts
- 18.抽象模板方法———获取程序运行的时间
- wpf和winform的那点区别
- Oracle中函数/过程返回结果集的几种方式
- java求第几位数字_怎么得到一个数的第n位数字 急求大神帮助
- 计算机仿真实验报告实验原理简述,数控编程实验报告总结
- Microsoft Visio 2003下载地址
- 硬件加密芯片介绍 及 加密芯片选择(加密IC) 加密芯片原理
- 基于SSM【爱校图书馆管理系统】附源码+论文
- 双11后,第一批买家秀曝光……
- 有了域名空间服务器怎么做网站,有了域名和空间怎么建网站?
- 《虚拟仿真实验教学解决方案(BJBR)》(Yanlz+Unity+SteamVR+VR+AR+MR+HR+??BR??+??CR??+??DR??+??ER??+虚拟仿真+人机交互+立钻哥哥+==)
- JavaScript网页设计:用户登录页面
- OpenCV显示中文字体
- java集合之TreeMap 构造器 方法 比较器
- 计算机网络(ISP,因特网组成,分组交换,计算机网络性能,网络体系机构)
- 微信服务号开发----发送消息
- React中antd日期选择框,指定区间禁用时间
热门文章
- 【技术栈——00061】搭建关于python项目docker镜像的Dockerfile文件示例(自己的)
- UnityHub 下载unity 卡在最后不动,已解决
- 云计算时代,数据中心运维应该注意哪些问题?
- 《咸鱼分享》DNS反向解析
- 微信小程序产品定位及功能介绍
- 将电脑调成护眼色不一定起到护眼的功能
- 计算二维紧束缚模型费米面和nesting程序新思路
- 七个实用的分布式开源框架
- Poco C++库简介
- Codeforces Round #548 (Div. 2) C. Edgy Trees(dfs || 并查集)