baobao
5/13/2017 - 1:36 PM

なんちゃってBloom

なんちゃってBloom

Shader "Hidden/Bloom"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        CGINCLUDE
        #include "UnityCG.cginc"
        sampler2D _MainTex;
        sampler2D _Tmp;
        float _Strength;
        float _SamplerCnt;
        float _Blur;
        float _Threshold;

        fixed4 frag0 (v2f_img i) : SV_Target
        {
            fixed4 col = tex2D(_MainTex, i.uv);
            // ピクセルの明るさ
            float bright = (col.r + col.g + col.b)/3;
            // 0 or 1
            float tmp = step(_Threshold, bright);
            return tex2D(_MainTex, i.uv) * tmp * _Strength;
        }

        fixed4 fragBlur (v2f_img i) : SV_Target
        {
            float u = 1 / _ScreenParams.x;
            float v = 1 / _ScreenParams.y;

            fixed4 result;
            // ぼかし
            for (float x = 0; x < _Blur; x++)
            {
                float xx = i.uv.x + (x - _Blur/2) * u;

                for (float y = 0; y < _Blur; y++)
                {
                    float yy = i.uv.y + (y - _Blur/2) * v;
                    fixed4 smp = tex2D(_Tmp, float2(xx, yy));
                    result += smp;
                }
            }

            result /= _Blur * _Blur;
            return tex2D(_MainTex, i.uv) + result;
        }

        ENDCG

        // Pass 0 bright sampling
        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag0
            ENDCG
        }

        // Pass 1 blur & 合成
        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment fragBlur
            ENDCG
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bloom : AbstractImageEffect
{
    // Bloomの強度
    [Range(0,1f)]
    public float strength = 0.3f;
    [Range(1,12)]
    public int samplerCnt = 6;
    // ブラーの強度
    [Range(1,64)]
    public int blur = 20;
    // 明るさのしきい値
    [Range(0,1f)]
    public float threshold = 0.3f;
    // RenderTextureサイズの分母
    [Range(1,12)]
    public int ratio = 1;

    protected override void _OnRenderImage (RenderTexture src, RenderTexture dest)
    {
        RenderTexture tmp = RenderTexture.GetTemporary (src.width / ratio, src.height / ratio, 0, RenderTextureFormat.ARGB32);
        tmp.filterMode = FilterMode.Bilinear;

        m_mat.SetFloat ("_SamplerCnt", samplerCnt);
        m_mat.SetFloat ("_Strength", strength);
        m_mat.SetFloat ("_Threshold", threshold);
        m_mat.SetFloat ("_Blur", blur);
        m_mat.SetTexture ("_Tmp", tmp);
        Graphics.Blit (src, tmp, m_mat, 0);

        // ぼかし + 合成
        Graphics.Blit (src, dest, m_mat, 1);

        RenderTexture.ReleaseTemporary (tmp);
    }
}
using UnityEngine;
/// <summary>
/// イメージエフェクトをサクッと試す用ベースクラス
/// </summary>
[ExecuteInEditMode]
public abstract class AbstractImageEffect : MonoBehaviour 
{
    Shader m_shader;
    protected Material m_mat;
    public string shaderName;

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (m_mat == null)
        {
            m_shader = Shader.Find(shaderName);
            m_mat = new Material(m_shader);
            m_mat.hideFlags = HideFlags.DontSave;
        }
        _OnRenderImage(src, dest);
    }
    protected virtual void _OnRenderImage (RenderTexture src, RenderTexture dest){Graphics.Blit(src, dest, m_mat);}
}