本日はShader学習枠です。
今回はShader表現の一つとしてサーバーグラフィックスでよく見る多角形の模様を作成します。
〇多角形の方程式
n角形の図形の方程式は次のようになります。
これをShaderLabで記述します。
〇多角形の処理
次の基礎的なスクリプトを作成しました。
Shader "Custom/NewSurfaceShader" { Properties { _Color ("Color", color) = (1.0, 1.0, 1.0, 1.0) } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include <Lighting.cginc> #include <UnityShaderUtilities.cginc> struct appdata { float4 vertex : POSITION; float2 uv: TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv :TEXCOORD0; }; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv= v.uv; return o; } // Color from the property section float4 _Color; float4 frag(v2f i) : SV_Target { return _Color; } ENDCG } } }
このShaderのを加工します。
まずは多角形を描く関数をさくせいします。
static const float PI = 3.14159265; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv= v.uv; return o; } float dPolygon(float2 p, int n, float size){ float a = atan2(p.x, p.y) + PI; float r = 2 * PI / n; return cos(floor(.5 + a / r) * r - a) * length(p) - size; }
[PI]は円周率を意味します。
次にUVを移動するための関数を作成します。
float map(float2 uv){ float2 iPos = floor(uv); float2 fPos = frac(uv); fPos.x = fPos.x * 1. - .5; fPos.y = fPos.y * 1. - .5; return dPolygon(fPos * _Pattern, _N, 0) - _Time.x * 3.; }
これによって多角形の値を扱うことができるようになりました。
最後にフラグメントシェーダーを編集します。
float4 frag(v2f i) : SV_Target { fixed4 col = _Color*(sin(map(i.uv) * 10) + 1) /1.6; return col; }
uv情報をmapに渡し、UV上で多角形を描きます。
これによって次の様に多角形が広がる演出を行えます。
〇Shader全文
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/NewSurfaceShader" { Properties { _Color ("Color", color) = (1.0, 1.0, 1.0, 1.0) _N("n",float)=6 _Pattern("pattern",float)=1 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include <Lighting.cginc> #include <UnityShaderUtilities.cginc> struct appdata { float4 vertex : POSITION; float2 uv: TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv :TEXCOORD0; }; static const float PI = 3.14159265; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv= v.uv; return o; } float dPolygon(float2 p, int n, float size){ float a = atan2(p.x, p.y) + PI; float r = 2 * PI / n; return cos(floor(.5 + a / r) * r - a) * length(p) - size; } float _Pattern; float _N; // Color from the property section float4 _Color; float map(float2 uv){ float2 fPos = frac(uv); fPos.x = fPos.x * 1. - .5; fPos.y = fPos.y * 1. - .5; return dPolygon(fPos * _Pattern, _N, 0) - _Time.x * 3.; } float4 frag(v2f i) : SV_Target { fixed4 col = _Color*(sin(map(i.uv) * 10) + 1) /1.6; return col; } ENDCG } } }