Unity shader学习之屏幕后期处理效果之Bloom效果

时间:2021-11-08 20:52:26

Bloom特效是游戏中常见的一种屏幕效果。这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果。

Bloom的实现原理很简单,首先根据一个阈值提取出图像中较亮的区域,把它们存储在一张渲染纹理中,再利用高斯模糊对这张渲染纹理进行模糊处理,模拟光线扩散的效果,最后再将其和原图像进行混合,得到最终的效果。

转载请注明出处:http://www.cnblogs.com/jietian331/p/7243444.html

如实现代码如下:

Unity shader学习之屏幕后期处理效果之Bloom效果Unity shader学习之屏幕后期处理效果之Bloom效果
 1 using UnityEngine;
2
3 public class BloomRenderer : PostEffectRenderer
4 {
5 [Range(0f, 4f)]
6 public float m_threshold = 0.4f; // 光阈值
7 [Range(1, 8)]
8 public int m_downSample = 2; // 降采样率
9 [Range(0, 4)]
10 public int m_iterations = 3; // 迭代次数
11 [Range(0.2f, 3f)]
12 public float m_blurSpread = 0.6f; // 模糊扩散量
13
14 protected override void OnRenderImage(RenderTexture src, RenderTexture dest)
15 {
16 int w = (int)(src.width / m_downSample);
17 int h = (int)(src.height / m_downSample);
18
19 RenderTexture buffer0 = RenderTexture.GetTemporary(w, h);
20 RenderTexture buffer1 = RenderTexture.GetTemporary(w, h);
21 buffer0.filterMode = FilterMode.Bilinear;
22 buffer1.filterMode = FilterMode.Bilinear;
23
24 // 提取亮光图
25 Mat.SetFloat("_Threshold", m_threshold);
26 Graphics.Blit(src, buffer0, Mat, 0);
27
28 // 将亮光图高斯模糊化
29 for (int i = 0; i < m_iterations; i++)
30 {
31 Mat.SetFloat("_BlurSpread", 1 + i * m_blurSpread);
32
33 Graphics.Blit(buffer0, buffer1, Mat, 1);
34 Graphics.Blit(buffer1, buffer0, Mat, 2);
35 }
36
37 // 将亮光图与原图混合
38 Mat.SetTexture("_Bloom", buffer0);
39 Graphics.Blit(src, dest, Mat, 3);
40
41 RenderTexture.ReleaseTemporary(buffer0);
42 RenderTexture.ReleaseTemporary(buffer1);
43 }
44
45 protected override string ShaderName
46 {
47 get { return "Custom/Bloom"; }
48 }
49 }
BloomRenderer

 

shader如下:

Unity shader学习之屏幕后期处理效果之Bloom效果Unity shader学习之屏幕后期处理效果之Bloom效果
  1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
2
3 Shader "Custom/Bloom"
4 {
5 Properties
6 {
7 _MainTex("Main Texture", 2D) = "white" {}
8 _Threshold("Threshold", float) = 0.6
9 _Bloom("Bloom", 2D) = "white" {}
10 }
11
12 SubShader
13 {
14 ZTest Always
15 ZWrite Off
16 Cull Off
17
18 Pass
19 {
20 CGPROGRAM
21 #pragma vertex vert
22 #pragma fragment frag
23
24 sampler2D _MainTex;
25 float _Threshold;
26
27 struct appdata
28 {
29 float4 vertex : POSITION;
30 float2 uv : TEXCOORD0;
31 };
32
33 struct v2f
34 {
35 float4 pos : SV_POSITION;
36 float2 uv : TEXCOORD0;
37 };
38
39 v2f vert(appdata v)
40 {
41 v2f o;
42 o.pos = UnityObjectToClipPos(v.vertex);
43 o.uv = v.uv;
44 return o;
45 }
46
47 fixed4 frag(v2f i) : SV_TARGET
48 {
49 fixed4 tex = tex2D(_MainTex, i.uv);
50 float lumiance = dot(fixed3(0.2125, 0.7154, 0.0721), tex.rgb);
51 return tex * saturate(lumiance - _Threshold);
52 }
53
54 ENDCG
55 }
56
57 UsePass "Custom/Gaussian Blur/HORIZONTAL"
58 UsePass "Custom/Gaussian Blur/VERTICAL"
59
60 Pass
61 {
62 CGPROGRAM
63 #pragma vertex vert
64 #pragma fragment frag
65
66 sampler2D _MainTex;
67 sampler2D _Bloom;
68
69 struct appdata
70 {
71 float4 vertex : POSITION;
72 float2 uv : TEXCOORD0;
73 };
74
75 struct v2f
76 {
77 float4 pos : SV_POSITION;
78 float2 uv : TEXCOORD0;
79 };
80
81 v2f vert(appdata v)
82 {
83 v2f o;
84 o.pos = UnityObjectToClipPos(v.vertex);
85 o.uv = v.uv;
86 return o;
87 }
88
89 fixed4 frag(v2f i) : SV_TARGET
90 {
91 fixed4 tex = tex2D(_MainTex, i.uv);
92 fixed4 bloom = tex2D(_Bloom, i.uv);
93 return fixed4(tex.rgb + bloom.rgb, tex.a);
94 }
95
96 ENDCG
97 }
98 }
99
100 Fallback Off
101 }
Custom/Bloom

 

调整参数:

Unity shader学习之屏幕后期处理效果之Bloom效果

效果如下:

Unity shader学习之屏幕后期处理效果之Bloom效果 Unity shader学习之屏幕后期处理效果之Bloom效果