Unity shader学习之屏幕后期处理效果之Bloom效果
Bloom特效是游戏中常见的一种屏幕效果。这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果。
Bloom的实现原理很简单,首先根据一个阈值提取出图像中较亮的区域,把它们存储在一张渲染纹理中,再利用高斯模糊对这张渲染纹理进行模糊处理,模拟光线扩散的效果,最后再将其和原图像进行混合,得到最终的效果。
转载请注明出处:http://www.cnblogs.com/jietian331/p/7243444.html
如实现代码如下:
using UnityEngine; public class BloomRenderer : PostEffectRenderer
{
[Range(0f, 4f)]
public float m_threshold = 0.4f; // 光阈值
[Range(, )]
public int m_downSample = ; // 降采样率
[Range(, )]
public int m_iterations = ; // 迭代次数
[Range(0.2f, 3f)]
public float m_blurSpread = 0.6f; // 模糊扩散量 protected override void OnRenderImage(RenderTexture src, RenderTexture dest)
{
int w = (int)(src.width / m_downSample);
int h = (int)(src.height / m_downSample); RenderTexture buffer0 = RenderTexture.GetTemporary(w, h);
RenderTexture buffer1 = RenderTexture.GetTemporary(w, h);
buffer0.filterMode = FilterMode.Bilinear;
buffer1.filterMode = FilterMode.Bilinear; // 提取亮光图
Mat.SetFloat("_Threshold", m_threshold);
Graphics.Blit(src, buffer0, Mat, ); // 将亮光图高斯模糊化
for (int i = ; i < m_iterations; i++)
{
Mat.SetFloat("_BlurSpread", + i * m_blurSpread); Graphics.Blit(buffer0, buffer1, Mat, );
Graphics.Blit(buffer1, buffer0, Mat, );
} // 将亮光图与原图混合
Mat.SetTexture("_Bloom", buffer0);
Graphics.Blit(src, dest, Mat, ); RenderTexture.ReleaseTemporary(buffer0);
RenderTexture.ReleaseTemporary(buffer1);
} protected override string ShaderName
{
get { return "Custom/Bloom"; }
}
}
BloomRenderer
shader如下:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/Bloom"
{
Properties
{
_MainTex("Main Texture", 2D) = "white" {}
_Threshold("Threshold", float) = 0.6
_Bloom("Bloom", 2D) = "white" {}
} SubShader
{
ZTest Always
ZWrite Off
Cull Off Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag sampler2D _MainTex;
float _Threshold; struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
}; v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
} fixed4 frag(v2f i) : SV_TARGET
{
fixed4 tex = tex2D(_MainTex, i.uv);
float lumiance = dot(fixed3(0.2125, 0.7154, 0.0721), tex.rgb);
return tex * saturate(lumiance - _Threshold);
} ENDCG
} UsePass "Custom/Gaussian Blur/HORIZONTAL"
UsePass "Custom/Gaussian Blur/VERTICAL" Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag sampler2D _MainTex;
sampler2D _Bloom; struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
}; v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
} fixed4 frag(v2f i) : SV_TARGET
{
fixed4 tex = tex2D(_MainTex, i.uv);
fixed4 bloom = tex2D(_Bloom, i.uv);
return fixed4(tex.rgb + bloom.rgb, tex.a);
} ENDCG
}
} Fallback Off
}
Custom/Bloom
调整参数:

效果如下:

Unity shader学习之屏幕后期处理效果之Bloom效果的更多相关文章
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
- Unity shader学习之屏幕后期处理效果之运动模糊
运动模糊,代码如下: using UnityEngine; public class MotionBlurRenderer : PostEffectRenderer { [Range(0.1f, 0. ...
- Unity shader学习之屏幕后期处理效果之均值模糊
均值模糊,也使用卷积来实现,之不过卷积中每个值均相等,且相加等于1. 代码如下, 子类: using UnityEngine; public class MeanBlurRenderer : Post ...
- Unity shader学习之屏幕后期处理效果之边缘检测
边缘检测的原理是利用一些边缘检测算子对图像进行卷积操作. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7232707.html 例如: 代码如下: usin ...
- Unity shader学习之屏幕后期处理效果之高度雾,重建world pos方法2
这里使用一种更高效地从深度纹理中重建世界坐标的方法. 首先计算摄像机的视锥体的四条射线向量进行线性插值,插值后的值便是该像素在世界空间坐标下到摄像机的方向. 然后通过与深度值相乘即可得到摄像机位置到该 ...
- Unity shader学习之屏幕后期效果之调整屏幕亮度,饱和度,对比度
Unity的屏幕后期处理效果,使用MonoBehaviour.OnRenderImage来实现. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7228063 ...
- Unity Shader 学习之旅
Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...
- Unity Shader 学习之旅之SurfaceShader
Unity Shader 学习之旅之SurfaceShader unity shader 图形图像 如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...
- 第四章 开始Unity Shader学习之旅(3)
1. 程序员的烦恼:Debug 调试(debug),大概是所有程序员的噩梦.而不幸的是,对一个Shader进行调试更是噩梦中的噩梦.这也是造成Shader难写的原因之一--如果发现得到的效果不对,我们 ...
随机推荐
- LITTLE-ENDIAN(小字节序、低字节序) BOM——Byte Order Mark 字节序标记 数据在内存中的存放顺序
总结: 1. endian 字节存放次序 字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了). 2. LITTLE-ENDIA ...
- php之print_r
stdClass类是PHP的一个内部保留类,初始时没有成员变量也没有成员方法,所有的魔术方法都被 设置为null,可以使用其传递变量参数,但是没有可以调用的方法.stdClass类可以被继承. 只是这 ...
- [daily] pandoc
学了LaTeX之后,你就会很自然的接触的另一种观点: LaTeX是专注于排版的,你需要专注于内容. 于是,请使用pandoc. 简单的说, pandoc就是可以将各种个样格式的文档转换成各种各样格式的 ...
- Java设计模式之模板模式及使用场景
模板模式,顾名思义,就是通过模板拓印的方式. 定义模板,就是定义框架.结构.原型.定义一个我们共同遵守的约定. 定义了模板,我们的剩余工作就是对其进行充实.丰润,完善它的不足之处. 定义模板采用抽象类 ...
- Requirejs 使用
代码地址 参考地址1 参考地址2 一.不依赖其他模块的module创建 创建math的module // math.js define(function (){ var add = function ...
- 10.5-uC/OS-III内部任务(时基任务OS-TickTask())
几乎所有的实时系统都需要有一个能提供周期性时间的时间源,叫做时基周期或系统周期. uC/OS-III的时基周期处理程序封装在OS_TICK.C文件中. OS_TickTask()任务被uC/OS-II ...
- Intellij IDEA中修改Maven项目的项目名称
1. 原项目名:votesystem-redis 想要重命名成新项目名:votesystem 2. 我们对此项目名进行Rename 3. 再对此项目所在的目录下进行修改 4. 重新打开项目 若 ...
- Ubuntu上Xilinx ARM交叉编译器安装
1,Windows中下载交叉编译器 2,在ubuntu中创建zedboard目录,并将交叉编译器复制进来 3,将该交叉编译器设置成可执行程序 chmod a+x xilinx-2011.09-50 ...
- mysql创建计算列(5.7以后才有)
mysql创建计算列 mysql> create table t(id int auto_increment not null,c1 int,c2 int,c3 int as (c1+c2) ...
- c# ThreadPool 判断子线程全部执行完毕的四种方法
1.先来看看这个 多线程编程 多线程用于数据采集时,速度明显很快,下面是基本方法,把那个auto写成采集数据方法即可. using System; using System.Collections.G ...