Unity Shader-后处理:Bloom全屏泛光
一.简介
二.原理介绍
1.HDR
2.Bloom
三.代码实现
- using UnityEngine;
- using System.Collections;
- [ExecuteInEditMode]
- public class BloomEffect : PostEffectBase
- {
- //分辨率
- public int downSample = 1;
- //采样率
- public int samplerScale = 1;
- //高亮部分提取阈值
- public Color colorThreshold = Color.gray;
- //Bloom泛光颜色
- public Color bloomColor = Color.white;
- //Bloom权值
- [Range(0.0f, 1.0f)]
- public float bloomFactor = 0.5f;
- void OnRenderImage(RenderTexture source, RenderTexture destination)
- {
- if (_Material)
- {
- //申请两块RT,并且分辨率按照downSameple降低
- RenderTexture temp1 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
- RenderTexture temp2 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0, source.format);
- //直接将场景图拷贝到低分辨率的RT上达到降分辨率的效果
- Graphics.Blit(source, temp1);
- //根据阈值提取高亮部分,使用pass0进行高亮提取
- _Material.SetVector("_colorThreshold", colorThreshold);
- Graphics.Blit(temp1, temp2, _Material, 0);
- //高斯模糊,两次模糊,横向纵向,使用pass1进行高斯模糊
- _Material.SetVector("_offsets", new Vector4(0, samplerScale, 0, 0));
- Graphics.Blit(temp2, temp1, _Material, 1);
- _Material.SetVector("_offsets", new Vector4(samplerScale, 0, 0, 0));
- Graphics.Blit(temp1, temp2, _Material, 1);
- //Bloom,将模糊后的图作为Material的Blur图参数
- _Material.SetTexture("_BlurTex", temp2);
- _Material.SetVector("_bloomColor", bloomColor);
- _Material.SetFloat("_bloomFactor", bloomFactor);
- //使用pass2进行景深效果计算,清晰场景图直接从source输入到shader的_MainTex中
- Graphics.Blit(source, destination, _Material, 2);
- //释放申请的RT
- RenderTexture.ReleaseTemporary(temp1);
- RenderTexture.ReleaseTemporary(temp2);
- }
- }
- }
- Shader "Custom/BloomEffect" {
- Properties{
- _MainTex("Base (RGB)", 2D) = "white" {}
- _BlurTex("Blur", 2D) = "white"{}
- }
- CGINCLUDE
- #include "UnityCG.cginc"
- //用于阈值提取高亮部分
- struct v2f_threshold
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- };
- //用于blur
- struct v2f_blur
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- float4 uv01 : TEXCOORD1;
- float4 uv23 : TEXCOORD2;
- float4 uv45 : TEXCOORD3;
- };
- //用于bloom
- struct v2f_bloom
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- float2 uv1 : TEXCOORD1;
- };
- sampler2D _MainTex;
- float4 _MainTex_TexelSize;
- sampler2D _BlurTex;
- float4 _BlurTex_TexelSize;
- float4 _offsets;
- float4 _colorThreshold;
- float4 _bloomColor;
- float _bloomFactor;
- //高亮部分提取shader
- v2f_threshold vert_threshold(appdata_img v)
- {
- v2f_threshold o;
- o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- o.uv = v.texcoord.xy;
- //dx中纹理从左上角为初始坐标,需要反向
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0)
- o.uv.y = 1 - o.uv.y;
- #endif
- return o;
- }
- fixed4 frag_threshold(v2f_threshold i) : SV_Target
- {
- fixed4 color = tex2D(_MainTex, i.uv);
- //仅当color大于设置的阈值的时候才输出
- return saturate(color - _colorThreshold);
- }
- //高斯模糊 vert shader(上一篇文章有详细注释)
- v2f_blur vert_blur(appdata_img v)
- {
- v2f_blur o;
- _offsets *= _MainTex_TexelSize.xyxy;
- o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- o.uv = v.texcoord.xy;
- 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;
- }
- //高斯模糊 pixel shader(上一篇文章有详细注释)
- fixed4 frag_blur(v2f_blur i) : SV_Target
- {
- fixed4 color = fixed4(0,0,0,0);
- color += 0.40 * 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;
- }
- //Bloom效果 vertex shader
- v2f_bloom vert_bloom(appdata_img v)
- {
- v2f_bloom o;
- //mvp矩阵变换
- o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- //uv坐标传递
- o.uv.xy = v.texcoord.xy;
- o.uv1.xy = o.uv.xy;
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0)
- o.uv.y = 1 - o.uv.y;
- #endif
- return o;
- }
- fixed4 frag_bloom(v2f_bloom i) : SV_Target
- {
- //取原始清晰图片进行uv采样
- fixed4 ori = tex2D(_MainTex, i.uv1);
- //取模糊普片进行uv采样
- fixed4 blur = tex2D(_BlurTex, i.uv);
- //输出= 原始图像,叠加bloom权值*bloom颜色*泛光颜色
- fixed4 final = ori + _bloomFactor * blur * _bloomColor;
- return final;
- }
- ENDCG
- SubShader
- {
- //pass 0: 提取高亮部分
- Pass
- {
- ZTest Off
- Cull Off
- ZWrite Off
- Fog{ Mode Off }
- CGPROGRAM
- #pragma vertex vert_threshold
- #pragma fragment frag_threshold
- ENDCG
- }
- //pass 1: 高斯模糊
- Pass
- {
- ZTest Off
- Cull Off
- ZWrite Off
- Fog{ Mode Off }
- CGPROGRAM
- #pragma vertex vert_blur
- #pragma fragment frag_blur
- ENDCG
- }
- //pass 2: Bloom效果
- Pass
- {
- ZTest Off
- Cull Off
- ZWrite Off
- Fog{ Mode Off }
- CGPROGRAM
- #pragma vertex vert_bloom
- #pragma fragment frag_bloom
- ENDCG
- }
- }
- }
注:PostEffectBase类是后处理类的基类,在前面的文章已有详细介绍,这里不再贴出。
四.效果展示
本篇文章介绍的主要是全屏泛光的实现方式,也就是泛光的部分只是通过一个全屏的颜色阈值来进行设定,超过这一阈值的颜色就进行泛光操作,否则不会泛光。这样做效率较高,但是没办法控制单独的物体进行泛光。网上也有这种针对单独对象的bloom操作,可以实现更加细致的Bloom效果,这篇文章可以进行参考。
Unity Shader-后处理:Bloom全屏泛光的更多相关文章
- Unity Shader后处理-搜索灰度效果
如U3D中Hierarchy面板下的搜索效果: 讲解分析: 1.这种PostEffect效果其实就是指Unity shader的后处理,即游戏中实现屏幕特效的常见方法.顾名思义屏幕后处理就是指在渲染完 ...
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
建立一个基本的屏幕后处理脚本系统 屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效.使用这种技术,可以为游戏画面添加更多艺术效果,例如景深. ...
- Unity Shader 屏幕后效果——Bloom外发光
Bloom的原理很简单,主要是提取渲染图像中的亮部区域,并对亮部区域进行模糊处理,再与原始图像混合而成. 一般对亮部进行模糊处理的部分采用高斯模糊,关于高斯模糊,详见之前的另一篇博客: https:/ ...
- Unity shader学习之屏幕后期处理效果之Bloom效果
Bloom特效是游戏中常见的一种屏幕效果.这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果. Bloom的实现原理很简单,首先根据一个阈值提取出 ...
- 【我的书】Unity Shader的书 — 文件夹(2015.12.21更新)
写在前面 感谢全部点进来看的朋友.没错.我眼下打算写一本关于Unity Shader的书. 出书的目的有以下几个: 总结我接触Unity Shader以来的历程,给其它人一个借鉴.我非常明确学Shad ...
- 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)
写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shad ...
- Unity Shader 入门精要学习 (冯乐乐 著)
第1篇 基础篇 第1章 欢迎来到Shader的世界 第2章 渲染流水线 第3章 Unity Shader 基础 第4章 学习Shader所需的数学基础 第2篇 初级篇 第5章 开始Unity Shad ...
- 【转】《Unity Shader入门精要》冯乐乐著 书中彩图
为方便个人手机学习时候查阅,从网上转来这些彩图. 如属过当行为,联系本人删除. 勘错表 http://candycat1992.github.io/unity_shaders_book/unity_s ...
- Unity Shader 知识点总结(二)
紧接着上一篇文章的shader入门知识的总结,本文主要总结shader中的纹理贴图.透明度混合.顶点动画.后期特效处理等操作.如果有什么地方有错,请指出更正,谢谢.本文的代码主要来自开源书:unity ...
- 小强学渲染之Unity Shader噪声应用
之前玩Tencent的仙剑4手游时,杀死boss会看到boss有“消融”的效果,就是身体上有多个洞洞然后往四周扩散直至尸体完全消失,但效果是没有关闭背面剔除的“穿帮”效果,可能也是考虑性能因素. em ...
随机推荐
- 《java程序设计》结对编程-四则运算(第一周-阶段总结)
一.需求分析(描述自己对需求的理解,以及后续扩展的可能性) 实现一个命令行程序,要求: - 自动生成小学四则运算题目(加,减,乘,除) - 支持整数 - 支持多运算符(比如生成包含100个运算符的题目 ...
- OCM_第十八天课程:Section8 —》RAC 数据库 _ RAC DB 搭建/RAC DB 配置使用
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- Java编码与乱码问题
一.为什么要编码? 由于人类的语言太多,因而表示这些语言的符号太多,无法用计算机的一个基本的存储单元----byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解. byte一个字节即8 ...
- Java多线程中wait语句的具体使用技巧
Java多线程在使用的时候会有很多语句需要我们具体的学习,在这其中wait()就是其中的一个.当然我们需要不断的努力学习才能掌握这一个语句的应用,下面的代码会对你学习Java多线程有所帮助. clas ...
- 分享一些 Java 无关基础方面的书籍
个人认为看书有两个点好处: 1. 能出版出来的书一定是经过反复思考,雕琢和审核的,因此从专业性的角度来说,一本好书的价值超其他资料 2. 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好 ...
- wap页面缩放
html{font-size: 100%;}.in-main{ min-width:320px; max-width:640px; margin:0 auto; font-size:14px; bac ...
- pyhon----模块导入
正常情况 报错(两个导入都报错)
- openj 4004 01背包问题求方案数
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define ...
- iOS学习笔记之异步图片下载
写在前面 在iOS开发中,无论是在UITableView还是在UICollectionView中,通过网络获取图片设置到cell上是较为常见的需求.尽管有很多现存的第三方库可以将下载和缓存功能都封装好 ...
- 2018-2019-2 网络对抗技术 20165333 Exp1 PC平台逆向破解
1 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串.该程序同 ...