Unity Shader 屏幕后效果——Bloom外发光

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

 

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

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

 

计算方法:

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

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

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

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

 

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

 

控制脚本:

 1 using UnityEngine;
 2 
 3 public class BloomCtrl : ScreenEffectBase
 4 {
 5     private const string _LuminanceThreshold = "_LuminanceThreshold";
 6     private const string _BlurSize = "_BlurSize";
 7     private const string _Bloom = "_Bloom";
 8 
 9     [Range(0, 4)]
10     public int iterations = 3;
11     [Range(0.2f, 3.0f)]
12     public float blurSize = 0.6f;
13     [Range(1, 8)]
14     public int dowmSample = 2;
15     [Range(0.0f, 4.0f)]
16     public float luminanceThreshold = 0.6f;//控制Bloom效果的亮度阈值,因为亮度值大多数时不大于1,故该值超过1时一般无效果,但开启HDR后图像的亮度取值范围将扩大
17 
18     private void OnRenderImage(RenderTexture source, RenderTexture destination)
19     {
20         if (Material != null)
21         {
22             Material.SetFloat(_LuminanceThreshold, luminanceThreshold);
23 
24             int rth = source.height / dowmSample;
25             int rtw = source.width / dowmSample;
26 
27             RenderTexture buffer0 = RenderTexture.GetTemporary(rtw, rth, 0);
28             buffer0.filterMode = FilterMode.Bilinear;
29 
30             //第1个Pass中提取纹理亮部,存到buffer0中,以便后面进行高斯模糊处理
31             Graphics.Blit(source, buffer0,Material,0);
32 
33             for(int i = 0; i < iterations; i++)
34             {
35                 Material.SetFloat(_BlurSize, blurSize*i+1.0f);
36 
37                 //第2,3个Pass中对亮部分别进行纵向和横向的渲染处理(高斯模糊)
38                 RenderTexture buffer1 = RenderTexture.GetTemporary(rtw, rth, 0);
39                 Graphics.Blit(buffer0, buffer1, Material,1);
40                 RenderTexture.ReleaseTemporary(buffer0);//临时创建的渲染纹理不能直接释放 x: buffer0.Release();
41 
42                 buffer0 = RenderTexture.GetTemporary(rtw, rth, 0);
43                 Graphics.Blit(buffer1, buffer0, Material, 2);
44                 RenderTexture.ReleaseTemporary(buffer1);
45             }
46 
47             //第4个Pass将buffer0高斯模糊后的结果传给_Bloom以进行最后的混合
48             Material.SetTexture(_Bloom, buffer0);
49             Graphics.Blit(source,destination,Material,3);//注意这里用原始纹理作为源纹理而不是buffer0,因为buffer0已经作为另一个参数进行了传递,而这里还需要原始的纹理以进行混合
50             RenderTexture.ReleaseTemporary(buffer0);
51         }
52         else
53             Graphics.Blit(source, destination);
54     }
55 }

基类脚本见:

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

 

Shader脚本:

  1 Shader "MyUnlit/Bloom"
  2 {
  3     Properties
  4     {
  5         _MainTex ("Texture", 2D) = "white" {}
  6         _Bloom("Bloom",2D)="black"{}
  7         _LuminanceThreshold("Luminance Threshold",Float)=0.5
  8         _BlurSize("Blur Size",Float)=1.0
  9     }
 10     SubShader
 11     {
 12         CGINCLUDE
 13 
 14         #include "UnityCG.cginc"
 15 
 16         sampler2D _MainTex;
 17         half4 _MainTex_TexelSize;
 18         sampler2D _Bloom;
 19         float _LuminanceThreshold;
 20         float _BlurSize;
 21 
 22         struct v2f
 23         {
 24            half2 uv : TEXCOORD0;
 25            float4 pos : SV_POSITION;
 26         };
 27 
 28         struct v2fBloom
 29         {
 30            //half4是因为这里还要存储_Bloom纹理
 31            half4 uv:TEXCOORD0;
 32            float4 pos:SV_POSITION;
 33         };
 34 
 35         v2f vert(appdata_img v)
 36         {
 37            v2f o;
 38            o.pos=UnityObjectToClipPos(v.vertex);
 39            o.uv=v.texcoord;    
 40            return o;
 41         }
 42 
 43         v2fBloom vertBloom(appdata_img v)
 44         {
 45            v2fBloom o;
 46            o.pos=UnityObjectToClipPos(v.vertex);
 47 
 48            //xy存储主纹理,zw存储_Bloom纹理,这样不必再申请额外空间
 49            o.uv.xy=v.texcoord;
 50            o.uv.zw=v.texcoord;
 51 
 52            //纹理坐标平台差异化判断,主要针对DirectX,因为DirectX与OpenGL纹理坐标原点不同(分别在左上和左下)
 53            //同时Unity平台对于主纹理已经进行过内部处理,因此这里只需要对_Bloom纹理进行平台检测和翻转
 54            //主要表现为进行y轴方向的翻转(因为y轴方向相反),对于_Bloom纹理来说也就是w
 55            #if UNITY_UV_STARTS_AT_TOP
 56            if(_MainTex_TexelSize.y<0){
 57                   o.uv.w=1.0-o.uv.w;
 58            }
 59            #endif
 60 
 61            return o;
 62         }
 63 
 64         //提取超过亮度阈值的图像
 65         fixed4 fragExtractBright(v2f i):SV_Target
 66         {
 67             fixed4 col=tex2D(_MainTex,i.uv);
 68             fixed val=clamp(Luminance(col)-_LuminanceThreshold,0.0,1.0);
 69             return col*val;
 70         }
 71 
 72         //对xy和zw对应的纹理采样进行混合
 73         fixed4 fragBloom(v2fBloom i):SV_Target
 74         {
 75             return tex2D(_MainTex,i.uv.xy)+tex2D(_Bloom,i.uv.zw);
 76         }
 77 
 78         ENDCG
 79 
 80         ZTest Always
 81         Cull Off
 82         ZWrite Off
 83 
 84         //Pass 1:提亮部
 85         Pass
 86         {
 87             CGPROGRAM
 88             #pragma vertex vert
 89             #pragma fragment fragExtractBright     
 90             ENDCG
 91         }
 92 
 93         //Pass 2,3:高斯模糊,这里直接调用以前写的Pass
 94         UsePass "MyUnlit/GaussianBlur/GAUSSIANBLUR_V"
 95 
 96         UsePass "MyUnlit/GaussianBlur/GAUSSIANBLUR_H"
 97 
 98         //Pass 4:混合原图和模糊后亮部
 99         Pass
100         {
101             CGPROGRAM
102             #pragma vertex vertBloom
103             #pragma fragment fragBloom
104             ENDCG
105         }
106     }
107     Fallback Off
108 }

 

效果如下:

 

转载于:https://www.cnblogs.com/koshio0219/p/11169122.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不要假装努力,结果不会陪你演戏!

转载于:https://www.cnblogs.com/strive-19970713/p/11171205.html

机器学习基石-作业二-第10题分析

题目如上图所示&#xff0c;答案是&#xff1a;&#xff1b;在网上看到的答案中有一个很好的解释就是说在一个n纬的欧几里德空间里&#xff0c;分别按照参数做一个垂直于每个轴的超平面&#xff0c;这些超平面能够打散这么多个点。首先我承认这个事实&#xff0c;具体的证明还没…

机器学习基石作业二中的DECISION_STUMP实现

概要&#xff1a;在林老的题目描述中&#xff0c;DECISION_STUMP&#xff08;其实就是“决策桩”&#xff0c;也就是只有一层的决策树&#xff09;。题目中提到了的选去是把属性&#xff08;一维的&#xff09;按照从小到大的顺序排列以后取两个挨着的值的平均值&#xff0c;网…

【MM系列】SAP 关于更改物料的价格控制类型

公众号&#xff1a;SAP Technical本文作者&#xff1a;matinal原文出处&#xff1a;http://www.cnblogs.com/SAPmatinal/ 原文链接&#xff1a;【MM系列】SAP 关于更改物料的价格控制类型前言部分 大家可以关注我的公众号&#xff0c;公众号里的排版更好&#xff0c;阅读更舒适…

机器学习基石-作业三-第2题分析以及通过H证明EIN的讨论

题目&#xff1a; 这是机器学习基石作业三种的第二小题&#xff0c;额&#xff0c;在网上看了很多解答&#xff08;解答也不多&#xff09;感觉都没有说清楚为什么&#xff0c;所以励志清楚滴解决一下这个问题&#xff0c;经过努力&#xff0c;自认为得到了详细的解答&#xff…

Nginx的平滑升级记录---适用于编译安装的Nginx

一、查看自己的Nginx的版本号 [rootlocalhost sbin]# cd /usr/local/nginx/sbin/ [rootlocalhost sbin]# ls nginx [rootlocalhost sbin]# ./nginx -V nginx version: nginx/1.15.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) configure arguments: 二、确定自己要…

02(c)多元无约束优化问题-牛顿法

此部分内容接《02(a)多元无约束优化问题》&#xff01; 第二类&#xff1a;牛顿法(Newton method) \[f({{\mathbf{x}}_{k}}\mathbf{\delta })\text{ }\approx \text{ }f({{\mathbf{x}}_{k}}){{\nabla }^{T}}f({{\mathbf{x}}_{k}})\cdot \mathbf{\delta }\frac{1}{2}{{\mathbf{\…

推荐系统浅浅的例子

对于推荐系统&#xff0c;有很多的很强大的算法。这里作为练习&#xff0c;只介绍基本的协同过滤算法&#xff08;userbased&#xff09;和FM&#xff08;通过梯度下降的角度&#xff0c;还可以通过交替优化的角度来看&#xff09;。 这里的例子是在七月算法的视频中看的&#…

TPL Dataflow .Net 数据流组件,了解一下?

回顾上文 作为单体程序&#xff0c;依赖的第三方服务虽不多&#xff0c;但是2C的程序还是有不少内容可讲&#xff1b; 作为一个常规互联网系统&#xff0c;无外乎就是接受请求、处理请求&#xff0c;输出响应。 由于业务渐渐增长&#xff0c;数据处理的过程会越来越复杂和冗长&…

推荐系统实例

协同过滤与隐语义模型 在机器学习问题中&#xff0c;我们见到的数据集通常是如下的格式&#xff1a; input target ... ... &#xff0c;一个输入向量的集合以及对应的数据集合,就是我们想要去预测的值。 对于…

【转】深入理解JavaScript闭包(closure)

文章来源&#xff1a;http://www.felixwoo.com/archives/247 最近在网上查阅了不少Javascript闭包(closure)相关的资料&#xff0c;写的大多是非常的学术和专业。对于初学者来说别说理解闭包了&#xff0c;就连文字叙述都很难看懂。撰写此文的目的就是用最通俗的文字揭开Java…

从头开始建立神经网络翻译及扩展

目录翻译从头开始建立神经网络-简介导包和配置生成一个数据集实现用来展示决策边界的辅助函数Logistic Regression训练一个神经网络我们的神经网络如何进行预测学习神经网络的参数实现神经网络训练一个隐层有3个神经元的神经网络验证隐层神经元个数对神经网络的影响练习练习题解…

对比 C++ 和 Python,谈谈指针与引用

花下猫语&#xff1a;本文是学习群内 樱雨楼 小姐姐的投稿。之前已发布过她的一篇作品《当谈论迭代器时&#xff0c;我谈些什么&#xff1f;》&#xff0c;大受好评。本文依然是对比 C 与 Python&#xff0c;来探讨编程语言中极其重要的概念。祝大家读有所获&#xff0c;学有所…

《吴恩达深度学习》第一课第四周任意层的神经网络实现及BUG处理

目录一、实现1、吴恩达提供的工具函数sigmoidsigmoid求导relurelu求导2、实现代码导包和配置初始化参数前向运算计算损失后向运算更新参数组装模型3、问题及思考一、实现 1、吴恩达提供的工具函数 这几个函数这里只是展示一下&#xff0c;这是吴恩达写好的工具类&#xff0c;…

球形坐标和Cartesian 坐标的转换 spherical coordinate

spherical coordinate 和cartesian坐标的转换&#xff0c; 个人认为在控制camera的时候最为有用&#xff0c;比如CS中的操作方式&#xff0c; 鼠标负责方向的改变&#xff0c;其恰恰就是球形坐标的改变。而camera的位置改变就是cartesian的改变&#xff0c;所以这两者的转换就必…

【HANA系列】SAP HANA Studio出现Fetching Children...问题

公众号&#xff1a;SAP Technical本文作者&#xff1a;matinal原文出处&#xff1a;http://www.cnblogs.com/SAPmatinal/ 原文链接&#xff1a;【ABAP系列】SAP HANA Studio出现"Fetching Children..."问题前言部分 大家可以关注我的公众号&#xff0c;公众号里的排版…

朴素Bayse新闻分类实践

目录1、信息增益&#xff08;互信息&#xff09;介绍&#xff08;1&#xff09;西瓜书中的信息增益[^1]&#xff08;2&#xff09;PRML中的互信息[^2]&#xff08;3&#xff09; 其实他们是一个东西2、朴素Bayse新闻分类[^3]&#xff08;1&#xff09;常量及辅助函数&#xff0…

【数据仓库】OLTP系统和OLAP系统区别

OLTP&#xff1a;联机事务处理系统(OnLine Transaction Processing) OLAP&#xff1a;联机分析处理系统(OnLine Analytical Processing) 参考文档&#xff1a; 操作数据库系统(OLTP)和联机分析处理系统(OLAP)的区别转载于:https://www.cnblogs.com/badboy200800/p/11189478.htm…