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

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 }
BloomRenderer

 

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 }
Custom/Bloom

 

调整参数:

效果如下:

 

posted @ 2017-07-27 10:29  孤独の巡礼  阅读(5856)  评论(0编辑  收藏  举报