• 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

    调整参数:

    效果如下:

     

  • 相关阅读:
    安全传输平台项目扩展——keymngserver重构-硬件扩展
    安全传输平台项目扩展——C复习-C++复习-keymngclient重构
    安全传输平台项目——客户端代码移植-项目模块总结
    安全传输平台项目——配置管理终端-读写数据库
    根号分治刷题记录
    使用netsh命令来管理IP安全策略
    关于make_shared无法访问非公有构造函数的解决方法
    两两交换链表中的节点-递归解法
    Spring 的 AOP 简介
    Spring IOC和DI 注解开发
  • 原文地址:https://www.cnblogs.com/jietian331/p/7243444.html
Copyright © 2020-2023  润新知