Unityのシェーダでディレクショナルブラーのポストエフェクト実装する方法です。
Unity2019.2.18
はじめに
この記事ではUnityのシェーダでディレクショナルブラーをかけるポストエフェクトを実装する方法をまとめます。
Unityでポストエフェクトを掛ける基本的な方法については以下の記事にまとめていますので、必要に応じて参照してください。
シェーダ
早速ですが、まずシェーダ全文を掲載します。
Shader "Example" { Properties { [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} _SampleCount ("Sample Count", int) = 5 _HorizontalIntensity ("Horizontal Intensity", Range(0.0, 1.0)) = 0.5 _BlurIntensity ("Blur Intensity", Range(0.0, 1.0)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; int _SampleCount; float _HorizontalIntensity; float _BlurIntensity; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { float2 offset = float2(_HorizontalIntensity, 1.0 - _HorizontalIntensity) * _BlurIntensity / _SampleCount; half3 rgb = 0; for (int j = 0; j < _SampleCount; j++) { half sign = (j % 2 * 2 - 1); // ループごとに交互に1と-1を取る符号 float2 uv = i.uv + offset * j * sign; rgb += tex2D(_MainTex, uv).rgb; } rgb /= _SampleCount; return fixed4(rgb, 1); } ENDCG } } }
実装はシンプルです。
まずブラーを掛けたい方向にUVをずらしてテクスチャをサンプリングします。
次にこれと反対方向にもう少し大きめにUVをずらしてサンプリングします。
つぎにまた反対方向に..とこれを交互に繰り返すことでブラーを作っています。
レンダリング結果
さてこれをポストエフェクトとしてレンダリングします。
ポストエフェクトを掛けるためのスクリプトは以下のように書きます。
using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private Material _material; [SerializeField, Range(1, 20)] private int _sampleCount = 5; [SerializeField, Range(0.0f, 1.0f)] private float _horizontalIntensity = 0.5f; [SerializeField, Range(0.0f, 1.0f)] private float _blurIntensity = 0.5f; private void OnRenderImage(RenderTexture source, RenderTexture dest) { _material.SetFloat("_SampleCount", _sampleCount); _material.SetFloat("_HorizontalIntensity", _horizontalIntensity); _material.SetFloat("_BlurIntensity", _blurIntensity); Graphics.Blit(source, dest, _material); } }
これをカメラにアタッチして実行すると以下の結果が得られます。
効果なし
Horizontal Intensity : 0.5
Blur Intensity : 0.04
Horizontal Intensity : 0.5
Blur Intensity : 0.1