本日は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
}
}
}