UnityのImageEffectShaderで遊んでみた(二次関数絡み、光の表現など)

# 1個目 とりあえずいろいろ動かした
回転、大きさ調節、サインカーブなどを使ってみた。
![投稿用オリジナルShader.gif](https://qiita-image-store.s3.amazonaws.com/0/113509/5ae2bd3a-5d5d-feb5-c435-f38877ece8d0.gif)

```
Shader "Original/OriginalEffectShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always
		// 追加
        CGINCLUDE

        #define PI 3.14159

        // (anti-aliased)Gridを作る関数
        float coordinateGrid(float2 r){
            float3 axisCol = float3(0.0, 0.0, 1.0);
            float3 gridCol = float3(0.5, 0.5, 0.5);
            float ret = 0.0;

            // Draw grid lines
            const float tickWidth = 0.1;
            for(float i= -2.0;i<2.0; i+= tickWidth){
                ret += 1.0 - smoothstep(0.0, 0.008, abs (r.x - i));
                ret += 1.0 - smoothstep(0.0, 0.008, abs (r.y - i));
            }

            // Draw the axis
            ret += 1.0-smoothstep(0.001, 0.015, abs(r.x));
            ret += 1.0-smoothstep(0.001, 0.015, abs(r.y));
            return ret;
        }

        // returns 1.0 if inside circle
        float disk(float2 r, float2 center, float radius){
            return 1.0 - smoothstep( radius - 0.005, radius + 0.005, length(r - center));
        }

        // returns 1.0 if inside the rect
        float rectangle(float2 r, float2 bottomLeft, float2 topRight){
            float ret;
            float d = 0.005;
            ret = smoothstep(bottomLeft.x - d, bottomLeft.x + d, r.x);
            ret *= smoothstep(bottomLeft.y - d, bottomLeft.y + d, r.y);
            ret *= 1.0 - smoothstep(topRight.y - d, topRight.y + d, r.y);
            ret *= 1.0 - smoothstep(topRight.x - d, topRight.x + d, r.x);
            return ret;
        }

        float mod(float  a, float  b) { return a-b*floor(a/b); } 
        ENDCG

		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;

			fixed4 frag (v2f i) : SV_Target
			{
				float2 r = 2.0 * (i.uv - 0.5);
                float aspectRatio = _ScreenParams.x / _ScreenParams.y;
                r.x *= aspectRatio;
                //長方形がはけてくための設定
                float2 t = r / (1 + mod(_Time.y, 20) * 0.05);
                float2 t1 = r / (1 + mod(_Time.y, 20) * 0.1);
                float2 t2 = r / (1 + mod(_Time.y, 20) * 0.15);

                fixed3 bgCol = float3(1.0, 1.0, 1.0); // white

                fixed3 col1 = float3(0.216, 0.471, 0.698); // blue
                fixed3 col2 = float3(1.00, 0.329, 0.298); // red
                fixed3 col3 = float3(0.867, 0.910, 0.247); // yellow
                fixed3 col4 = float3(0.537, 0.741, 0.408); //green

                fixed3 ret;
                ret = bgCol;
                float2 q = r + float2(-aspectRatio, 1.0);
                //右上から出てくる赤い円
                ret = lerp(ret, col2, disk(r, float2(-aspectRatio * 0.9, 0.8), 0.5));
                //後ろの青い円
                ret = lerp(ret, col1, disk(q, float2(0, 0), 2.5));
                //以下青い円の周りに赤い長方形を回すスクリプト
                float x = 2.7 * cos((PI * 0.7 + mod(_Time.y * 0.5, PI * 0.5))*1.0);
                float y = 2.7 * sin((PI * 0.7 + mod(_Time.y * 0.5, PI * 0.5))*1.0);
                float2 s = q - float2(x, y);
                float angle = _Time.y * 3.0;
                float2x2 rot = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
                s = mul(rot, s);
                ret = lerp(ret, col2, rectangle(s, float2(-0.06, -0.06), float2(0.06, 0.06)));
                //くねくねしてる緑の円
                float angle1 = 0.3;
                float2x2 rot1 = float2x2(cos(angle1), -sin(angle1), sin(angle1), cos(angle1));
                float2 p = mul(rot1, r);
                ret = lerp(ret, col4, disk(p, float2((mod(_Time.y  * 1.5, 2.0) - 1.0) * (aspectRatio + 0.2), sin(_Time.y * PI * 3) * 0.71), 0.1));
                //左下から出てくる緑
                ret = lerp(ret, col4, rectangle(p, float2(-1.5, -2.0), float2(0, -0.8)));
                float2x2 rot2 = float2x2(cos(angle/2), -sin(angle/2), sin(angle/2), cos(angle/2));
                float2 h = mul(rot2, q);
                ret = lerp(ret, col3, rectangle(h, float2(-0.7, -0.7), float2(0.7, 0.7)));
                //最初にある左上の青
                ret = lerp(ret, col1, smoothstep(1.5,1.51,-t.x + t.y));
                //左下の黄色
                ret = lerp(ret, col3, smoothstep(2.6, 2.6, -t1.x -4 * t1.y));
                //右の赤
                ret = lerp(ret, col2, smoothstep(2.3, 2.31, 3 * t2.x - t2.y));

                fixed3 pixel = ret;
                return fixed4(pixel, 1.0);
			}
			ENDCG
		}
	}
}

```

#2個目 二次関数とかあれこれいじってみた
二次関数に絶対値をつけたり、サインカーブを置いてみたり。
<img width="250" alt="投稿用オリジナルShader1.png" src="https://qiita-image-store.s3.amazonaws.com/0/113509/1f8c3e2c-264f-ffb0-78f6-9cb7f9f57731.png">

```
Shader "Original/Original1EffectShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always
		// 追加
        CGINCLUDE

        #define PI 3.14159

        // (anti-aliased)Gridを作る関数
        float coordinateGrid(float2 r){
            float3 axisCol = float3(0.0, 0.0, 1.0);
            float3 gridCol = float3(0.5, 0.5, 0.5);
            float ret = 0.0;

            // Draw grid lines
            const float tickWidth = 0.1;
            for(float i= -2.0;i<2.0; i+= tickWidth){
                ret += 1.0 - smoothstep(0.0, 0.008, abs (r.x - i));
                ret += 1.0 - smoothstep(0.0, 0.008, abs (r.y - i));
            }

            // Draw the axis
            ret += 1.0-smoothstep(0.001, 0.015, abs(r.x));
            ret += 1.0-smoothstep(0.001, 0.015, abs(r.y));
            return ret;
        }

        // returns 1.0 if inside circle
        float disk(float2 r, float2 center, float radius){
            return 1.0 - smoothstep( radius - 0.005, radius + 0.005, length(r - center));
        }

        // returns 1.0 if inside the rect
        float rectangle(float2 r, float2 bottomLeft, float2 topRight){
            float ret;
            float d = 0.005;
            ret = smoothstep(bottomLeft.x - d, bottomLeft.x + d, r.x);
            ret *= smoothstep(bottomLeft.y - d, bottomLeft.y + d, r.y);
            ret *= 1.0 - smoothstep(topRight.y - d, topRight.y + d, r.y);
            ret *= 1.0 - smoothstep(topRight.x - d, topRight.x + d, r.x);
            return ret;
        }

        float mod(float  a, float  b) { return a-b*floor(a/b); } 
        ENDCG

		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;

			fixed4 frag (v2f i) : SV_Target
			{
				float2 r = 2.0 * (i.uv - 0.5);
                float aspectRatio = _ScreenParams.x / _ScreenParams.y;
                r.x *= aspectRatio;

                fixed3 bgCol = float3(1.0, 1.0, 1.0); // white

                fixed3 col1 = float3(0.216, 0.471, 0.698); // blue
                fixed3 col2 = float3(1.00, 0.329, 0.298); // red
                fixed3 col3 = float3(0.867, 0.910, 0.247); // yellow

                fixed3 ret;
                ret = bgCol;

                //座標をずらす
                float2 s = r * 3;
                //真ん中の青い二次関数チックなところ(言い表し方わかりませんw)
                float y = abs(0.5 * (s.x - 2) * (s.x + 2)) - 2;
                ret = lerp(ret, col1, smoothstep(-s.y, -s.y + 0.1, -y));
                //逆になった山のようなところ
                float y1 = 0.5 * ((s.x - 0.5) * (s.x - 0.5) - 2 * abs(s.x - 1) - 4);
                ret = lerp(ret, col2, smoothstep(s.y, s.y + 0.1, y1));
                //下の波二つ
                ret = lerp(ret, bgCol, smoothstep(s.y, s.y + 0.1, -cos(s.x) - 2.5));
                ret = lerp(ret, col1, smoothstep(s.y, s.y + 0.1, -cos(s.x) - 3.5));
                //右のほうにある円
                ret = lerp(ret, col3, disk(r, float2(0.8 * aspectRatio, -0.3), 0.3));
                //左の長方形
                float angle = 0.2;
                float2x2 rot = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
                float2 t = r - float2(-1.4, -0.3);
                t = mul(rot, t);
                ret = lerp(ret, col1, rectangle(t, float2(-0.2, -0.2), float2(0.2, 0.2)));

                fixed3 pixel = ret;
                return fixed4(pixel, 1.0);
			}
			ENDCG
		}
	}
}

```

#3個目 光っぽさを出してみた
色を加算することで光っぽさが出る。
![iiiiaa.gif](https://qiita-image-store.s3.amazonaws.com/0/113509/9d495827-5033-4aad-e5a6-bd510928931f.gif)

```
Shader "Original/Original2EffectShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always
		// 追加
        CGINCLUDE

        #define PI 3.14159

        // (anti-aliased)Gridを作る関数
        float coordinateGrid(float2 r){
            float3 axisCol = float3(0.0, 0.0, 1.0);
            float3 gridCol = float3(0.5, 0.5, 0.5);
            float ret = 0.0;

            // Draw grid lines
            const float tickWidth = 0.1;
            for(float i= -2.0;i<2.0; i+= tickWidth){
                ret += 1.0 - smoothstep(0.0, 0.005, abs (r.x - i));
                ret += 1.0 - smoothstep(0.0, 0.005, abs (r.y - i));
            }

            // Draw the axis
            ret += 1.0-smoothstep(0.001, 0.01, abs(r.x));
            ret += 1.0-smoothstep(0.001, 0.01, abs(r.y));
            return ret;
        }

        // returns 1.0 if inside circle
        float disk(float2 r, float2 center, float radius){
            return 1.0 - smoothstep( radius - 0.005, radius + 0.005, length(r - center));
        }

        // returns 1.0 if inside the rect
        float rectangle(float2 r, float2 bottomLeft, float2 topRight){
            float ret;
            float d = 0.005;
            ret = smoothstep(bottomLeft.x - d, bottomLeft.x + d, r.x);
            ret *= smoothstep(bottomLeft.y - d, bottomLeft.y + d, r.y);
            ret *= 1.0 - smoothstep(topRight.y - d, topRight.y + d, r.y);
            ret *= 1.0 - smoothstep(topRight.x - d, topRight.x + d, r.x);
            return ret;
        }

        float mod(float  a, float  b) { return a-b*floor(a/b); } 
        ENDCG

		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;

			fixed4 frag (v2f i) : SV_Target
			{
				float2 r = 2.0 * (i.uv - 0.5);
                float aspectRatio = _ScreenParams.x / _ScreenParams.y;
                r.x *= aspectRatio;

                fixed3 bgCol = float3(0.0, 0.0, 0.0); // white

                fixed3 col1 = float3(0.216, 0.471, 0.698); // blue
                fixed3 col2 = float3(1.00, 0.329, 0.298); // red
                fixed3 col3 = float3(0.867, 0.910, 0.247); // yellow
                fixed3 col4 = float3(0.537, 0.741, 0.408); //green
                fixed3 col5 = (col1 + col2)/2;

                fixed3 ret;
                ret = bgCol;

                //青い光
                float t = (sin(_Time.y) - 0.5) * 0.2;//時間により変化する値
				float2 r2 = r - float2(0, - 1.2);//座標をずらす
				float angle = t * PI;//回転角
				float2x2 rotmat = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));//回転行列
				r2 = mul(rotmat, r2);//回転させる
                ret += col1 * (1.0 - smoothstep(0, abs(r2.y * 0.2 + 0.05), abs(r2.x))) * 0.5;//光の描画  以下同じ順番
                //赤い光
                t = (sin(_Time.y * 0.8) - 0.5) * 0.2;
                float2 s = r - float2(1.1, -1.2);
                angle = (-0.1 + t) * PI;
                rotmat = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
                s = mul(rotmat, s);
                ret += col2 * (1.0 - smoothstep(0, abs(s.y * 0.2 + 0.05), abs(s.x))) * 0.5;
                //黄色の光
                t = (sin(_Time.y * 1.2) - 0.5) * 0.2;
                float2 q = r - float2(-1.2, -1.4);
                angle = (-0.8 + t) * PI;
                rotmat = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
                q = mul(rotmat, q);
                ret += col3 * (1.0 - smoothstep(0, abs(q.y * 0.2 + 0.05), abs(q.x))) * 0.5;
                //緑の光
                t = (sin(_Time.y * 1.4) - 0.5) * 0.2;
                float2 u = r - float2(-2.0, -1.2);
                angle = (0.3 + t * 0.8) * PI;
                rotmat = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
                u = mul(rotmat, u);
                ret += col4 * (1.0 - smoothstep(0, abs(u.y * 0.2 + 0.05), abs(u.x))) * 0.5;

                fixed3 pixel = ret;
                return fixed4(pixel, 1.0);
			}
			ENDCG
		}
	}
}

```
#参考
[[Unity] ShaderTutorial2D](http://qiita.com/Teach/items/08701010e077b1933923)