Bloom的原理很简单,主要是提取渲染图像中的亮部区域,并对亮部区域进行模糊处理,再与原始图像混合而成。

一般对亮部进行模糊处理的部分采用高斯模糊,关于高斯模糊,详见之前的另一篇博客:

https://www.cnblogs.com/koshio0219/p/11152534.html

计算方法:

总共需要用到4个Pass,它们的顺序如下:

Pass 1:得到纹理的亮度值(灰度值),由此计算出亮部区域,传递给一个临时的新纹理,这里叫_Bloom

Pass 2,3:单独对_Bloom进行高斯模糊(纵横),_Bloom纹理更新

Pass 4:混合原始纹理和_Bloom纹理,得到最终效果

为了得到更为细致的Bloom效果,建议将游戏的颜色空间由默认的伽马空间转为线性空间,必要时还可开启HDR

控制脚本:

 using UnityEngine;

 public class BloomCtrl : ScreenEffectBase
{
private const string _LuminanceThreshold = "_LuminanceThreshold";
private const string _BlurSize = "_BlurSize";
private const string _Bloom = "_Bloom"; [Range(, )]
public int iterations = ;
[Range(0.2f, 3.0f)]
public float blurSize = 0.6f;
[Range(, )]
public int dowmSample = ;
[Range(0.0f, 4.0f)]
public float luminanceThreshold = 0.6f;//控制Bloom效果的亮度阈值,因为亮度值大多数时不大于1,故该值超过1时一般无效果,但开启HDR后图像的亮度取值范围将扩大 private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (Material != null)
{
Material.SetFloat(_LuminanceThreshold, luminanceThreshold); int rth = source.height / dowmSample;
int rtw = source.width / dowmSample; RenderTexture buffer0 = RenderTexture.GetTemporary(rtw, rth, );
buffer0.filterMode = FilterMode.Bilinear; //第1个Pass中提取纹理亮部,存到buffer0中,以便后面进行高斯模糊处理
Graphics.Blit(source, buffer0,Material,); for(int i = ; i < iterations; i++)
{
Material.SetFloat(_BlurSize, blurSize*i+1.0f); //第2,3个Pass中对亮部分别进行纵向和横向的渲染处理(高斯模糊)
RenderTexture buffer1 = RenderTexture.GetTemporary(rtw, rth, );
Graphics.Blit(buffer0, buffer1, Material,);
RenderTexture.ReleaseTemporary(buffer0);//临时创建的渲染纹理不能直接释放 x: buffer0.Release(); buffer0 = RenderTexture.GetTemporary(rtw, rth, );
Graphics.Blit(buffer1, buffer0, Material, );
RenderTexture.ReleaseTemporary(buffer1);
} //第4个Pass将buffer0高斯模糊后的结果传给_Bloom以进行最后的混合
Material.SetTexture(_Bloom, buffer0);
Graphics.Blit(source,destination,Material,);//注意这里用原始纹理作为源纹理而不是buffer0,因为buffer0已经作为另一个参数进行了传递,而这里还需要原始的纹理以进行混合
RenderTexture.ReleaseTemporary(buffer0);
}
else
Graphics.Blit(source, destination);
}
}

基类脚本见:

https://www.cnblogs.com/koshio0219/p/11131619.html

Shader脚本:

 Shader "MyUnlit/Bloom"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Bloom("Bloom",2D)="black"{}
_LuminanceThreshold("Luminance Threshold",Float)=0.5
_BlurSize("Blur Size",Float)=1.0
}
SubShader
{
CGINCLUDE #include "UnityCG.cginc" sampler2D _MainTex;
half4 _MainTex_TexelSize;
sampler2D _Bloom;
float _LuminanceThreshold;
float _BlurSize; struct v2f
{
half2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
}; struct v2fBloom
{
//half4是因为这里还要存储_Bloom纹理
half4 uv:TEXCOORD0;
float4 pos:SV_POSITION;
}; v2f vert(appdata_img v)
{
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
o.uv=v.texcoord;
return o;
} v2fBloom vertBloom(appdata_img v)
{
v2fBloom o;
o.pos=UnityObjectToClipPos(v.vertex); //xy存储主纹理,zw存储_Bloom纹理,这样不必再申请额外空间
o.uv.xy=v.texcoord;
o.uv.zw=v.texcoord; //纹理坐标平台差异化判断,主要针对DirectX,因为DirectX与OpenGL纹理坐标原点不同(分别在左上和左下)
//同时Unity平台对于主纹理已经进行过内部处理,因此这里只需要对_Bloom纹理进行平台检测和翻转
//主要表现为进行y轴方向的翻转(因为y轴方向相反),对于_Bloom纹理来说也就是w
#if UNITY_UV_STARTS_AT_TOP
if(_MainTex_TexelSize.y<){
o.uv.w=1.0-o.uv.w;
}
#endif return o;
} //提取超过亮度阈值的图像
fixed4 fragExtractBright(v2f i):SV_Target
{
fixed4 col=tex2D(_MainTex,i.uv);
fixed val=clamp(Luminance(col)-_LuminanceThreshold,0.0,1.0);
return col*val;
} //对xy和zw对应的纹理采样进行混合
fixed4 fragBloom(v2fBloom i):SV_Target
{
return tex2D(_MainTex,i.uv.xy)+tex2D(_Bloom,i.uv.zw);
} ENDCG ZTest Always
Cull Off
ZWrite Off //Pass 1:提亮部
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment fragExtractBright
ENDCG
} //Pass 2,3:高斯模糊,这里直接调用以前写的Pass
UsePass "MyUnlit/GaussianBlur/GAUSSIANBLUR_V" UsePass "MyUnlit/GaussianBlur/GAUSSIANBLUR_H" //Pass 4:混合原图和模糊后亮部
Pass
{
CGPROGRAM
#pragma vertex vertBloom
#pragma fragment fragBloom
ENDCG
}
}
Fallback Off
}

效果如下:

Unity Shader 屏幕后效果——Bloom外发光的更多相关文章

  1. Unity Shader 屏幕后效果——颜色校正

    屏幕后效果指的是,当前整个场景图已经渲染完成输出到屏幕后,再对输出的屏幕图像进行的操作. 在Unity中,一般过程通常是: 1.建立用于处理效果的shader和临时材质,给shader脚本传递需要控制 ...

  2. Unity Shader 屏幕后效果——边缘检测

    关于屏幕后效果的控制类详细见之前写的另一篇博客: https://www.cnblogs.com/koshio0219/p/11131619.html 这篇主要是基于之前的控制类,实现另一种常见的屏幕 ...

  3. Unity Shader 屏幕后效果——全局雾

    Unity内置的雾效需要在每个shader中分别编写,造成了极大的不便.这里利用屏幕后处理产生可单独控制且自由度更高的雾效. 屏幕后雾效的本质在于,通过深度纹理重构出每个像素在世界空间中的位置,根据得 ...

  4. Unity Shader 屏幕后效果——高斯模糊

    高斯模糊是图像模糊处理中非常经典和常见的一种算法,也是Bloom屏幕效果的基础. 实现高斯模糊同样用到了卷积的概念,关于卷积的概念和原理详见我的另一篇博客: https://www.cnblogs.c ...

  5. Unity Shader 屏幕后效果——景深

    景深效果的原理是,在摄像机的近裁剪平面和远裁剪平面之间可以设置一个焦距,在这个距离所在的平面上的物体最为清晰,而这个距离之前或之后的物体成像是一种模糊状态(根据距离逐渐模糊,最终达到最为模糊的状态). ...

  6. Unity Shader 屏幕后效果——摄像机运动模糊(速度映射图实现)

    速度映射图主要是为了得到每个像素相对于前一帧的运动矢量,其中一种方法是使用摄像机的深度纹理来推导. 推导过程如下: 先由深度纹理逆推出NDC(归一化的设备坐标)下的顶点坐标,利用VP矩阵(视角*投影矩 ...

  7. Unity Shader实现描边效果

    http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...

  8. Unity Shader 之 透明效果

    透明效果 透明效果一般有两种实现方法: 第一种,使用透明度测试(Alpha Test) 第二种,使用透明度混合(Alpha Blending) 透明度测试和透明度混合机制: 透明度测试(Alpha T ...

  9. Unity实现屏幕抖动效果(通过Camera Viewpoint实现)

    由于游戏死亡时一般都需要屏幕抖一下下. 所以百度了下相关写法,发现方法很多~~~ 找来找去,找到个简单粗暴地,啥都不需要,一个脚本拖动到Camera上就可以了 略微修改了一点点,share一下 usi ...

随机推荐

  1. 编译 datax

    datax 是阿里巴巴官方开源的一个数据同步工具,可以用于诸多数据源之间的同步,并且使用简单.效率高. datax 官方有提供编译好的版本,可以直接下载,但是其中包含有 BUG. 我最近遇到的一个问题 ...

  2. Python【day 13】内置函数01

    1.python3.6.2 一共有 68个内置函数2.分成6个大类 1.反射相关-4个 2.面向对象相关-9个 3.作用域相关--2个 1.globlas() #注意:最后是s,复数形式 查看全局作用 ...

  3. shell脚本实现自动化安装linux版本的loadrunner agent(centos6.8)

    #!/bin/bash #Centos6下安装LoadRunner负载机 #@author Agoly #@date #@source 高级测试技术交流圈: yum -y install expect ...

  4. 【Android】天气应用

    模仿华为的"天气"应用写的一个小Demo.部分功能.动画效果没有实现,也没有过多考虑性能.Bug等其它方面的因素.写这个Demo的初衷是想熟悉下目前网上常用的一些框架. Demo采 ...

  5. 【推荐】全球最全面的Telegram组群频道的集合网站 持续收集中

    全球最全面的Telegram组群频道的集合网站 https://www.telegramgroup.org Telegram 组群频道分享 可搜索自己想找的组群频道 从小白到大神,一个 telegra ...

  6. 原生 JavaScript 代替 jQuery【转】

    目录 用原生JavaScript代替jQuery Query Selector CSS & Style DOM Manipulation Ajax Events Utilities Promi ...

  7. 【转】面试还搞不懂redis,快看看这40道Redis面试题(含答案和思维导图)

    ———————————————— 版权声明:本文为CSDN博主「程序员追风」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog. ...

  8. ezdml设计数据库

    数据结构和设计的介绍 ezdml软件:https://www.lanzous.com/i6ew2pe 1 用ezdml设计数据表然后导出到mysql数据库中 点击生成模型 2 选择库 3 点击开始生成

  9. [原创]Appium与Appium desktop的区别

    1.两者都属于Appium 服务端 2.二者最新版本如下:地址:https://github.com/appium/appium-desktop/releases Appium 服务端支持的:地址:h ...

  10. 很不错的python 机器学习资源

    http://www.cuijiahua.com/resource.html 曾看过的书,感觉一些很有用的学习资料,推荐给大家! Python基础: 网络教程推荐: 系统学习python3可以看廖雪峰 ...