Bloom特效是游戲中常見的一種屏幕效果。這種特效可以模擬真實攝像機的一種圖像效果,它讓畫面中較亮的區域“擴散”到周圍的區域中,造成一種朦朧的效果。
Bloom的實現原理很簡單,首先根據一個閾值提取出圖像中較亮的區域,把它們存儲在一張渲染紋理中,再利用高斯模糊對這張渲染紋理進行模糊處理,模擬光線擴散的效果,最后再將其和原圖像進行混合,得到最終的效果。
轉載請注明出處:http://www.cnblogs.com/jietian331/p/7243444.html
如實現代碼如下:

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 }
shader如下:

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 }
調整參數:
效果如下: