18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-12-18

1個目 とりあえずいろいろ動かした

回転、大きさ調節、サインカーブなどを使ってみた。
投稿用オリジナルShader.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個目 二次関数とかあれこれいじってみた
二次関数に絶対値をつけたり、サインカーブを置いてみたり。
投稿用オリジナルShader1.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

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

18
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?