トイカメラ風のフィルター
トイカメラ風フィルターです。上下を暈すだけという、ちゃっちいテクニックです。
Shaderの練習のために作ってみました。
ぼかし画像を作る部分は標準アセットのBlurのほぼコピペです。
ぼかし画像を一枚しか作っていないこともあり、イマイチですね。本当は複数のぼかしレベルの画像を送るべきですが、今回は練習なので手抜きです。
using UnityEngine; public class ToyCameraImageEffect : MonoBehaviour { private Material material; private Material blurMaterial; //ぼかし回数 [Range(0,10)] public int iterations = 3; //ブラーのずらし量 [Range(0.0f,1.0f)] public float blurSpread = 0.6f; protected virtual void Awake() { { string shaderName = "Hidden/ToyCameraImageEffectShader"; Shader shader = Shader.Find( shaderName ); Debug.Assert( shader != null ); material = new Material( shader ); } { string shaderName = "Hidden/BlurEffectConeTap"; Shader shader = Shader.Find( shaderName ); Debug.Assert( shader != null ); blurMaterial = new Material( shader ); } } void Update() { } void fourTapCone (RenderTexture src, RenderTexture dest, int iteration) { float off = 0.5f + iteration*blurSpread; Graphics.BlitMultiTap (src, dest, blurMaterial, new Vector2(-off, -off), new Vector2(-off, off), new Vector2( off, off), new Vector2( off, -off) ); } void downSample4x (RenderTexture src, RenderTexture dest) { float off = 1.0f; Graphics.BlitMultiTap (src, dest, blurMaterial, new Vector2(-off, -off), new Vector2(-off, off), new Vector2( off, off), new Vector2( off, -off) ); } void OnRenderImage( RenderTexture src, RenderTexture dest ) { //ぼかしの画を作るために4分の一サイズの小さい一時バッファを作ります。 int rtW = src.width/4; int rtH = src.height/4; RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0); downSample4x (src, buffer); // Blur the small texture for(int i = 0; i < iterations; i++) { RenderTexture buffer2 = RenderTexture.GetTemporary(rtW, rtH, 0); fourTapCone (buffer, buffer2, i); RenderTexture.ReleaseTemporary(buffer); buffer = buffer2; } material.SetTexture( "_BlurTex", buffer ); Graphics.Blit( src, dest, material ); RenderTexture.ReleaseTemporary(buffer); } }
Shader↓
Shader "Hidden/ToyCameraImageEffectShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _BlurTex ("Blur Texture", 2D) = "white" {} _FilterTex ("Filter Texture", 2D) = "white" {} } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Fog { Mode Off } 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; }; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.uv; return o; } sampler2D _MainTex; sampler2D _BlurTex; sampler2D _FilterTex; fixed4 frag (v2f i) : SV_Target { fixed4 org = tex2D(_MainTex, i.uv); fixed4 blur = tex2D(_BlurTex, i.uv); fixed4 filter = tex2D(_FilterTex, i.uv); return lerp( org, blur, filter.r ); } ENDCG } } }