Shader でグリッドを表示させる方法について考える
画像を n分割する
グリッドを作成する前に 画像を n分割する方法を考える
画像を分割するためには frac 関数を利用する
frac 関数は「小数値の小数部分を返す」関数なので uv に 5を掛けた場合、下図のように 0 ~ 1 を5回繰り返す
fixed4 frag (v2f i) : SV_Target { return fixed4(frac(i.uv * 5), 1, 1); }
なのでフラグメント処理を上記のようにすることで下図のように5 ✕ 5 分割することができる
グリッドを表示する
先程利用した分割数に グリッドの幅 (0.1) を追加したものの結果を見てみると
※図の作成が面倒だったので分割数を2にしている
frac(i.uv * (2 + 0.1))
となりグリッドの幅 以下のところを別色で描画してやるといい感じでグリッドが表示できそう
fixed4 frag (v2f i) : SV_Target { if (frac(i.uv.x * (2 + 0.1)) < 0.1 || frac(i.uv.y * (2 + 0.1)) < 0.1) { return fixed4(0.5, 0.5, 0.5, 1); } return fixed4(1, 1, 1, 1); }
上記のフラグメント処理にすると下図のようになりグリッドが表示された
最終的なシェーダー
if文が利用されていたり、分割数やグリッドの幅固定値だったのを書き換えた最終的なシェーダが以下になります
Shader "Custom/Unlit/Grid" { Properties { _LineColor ("Line Color", Color) = (1,1,1,1) [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} [IntRange] _SplitCount("Split Count", Range(1, 30)) = 10 _LineSize("Line Size", Range(0.01, 1)) = 0.1 } SubShader { Tags { "RenderType"="Opaque" } 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; }; sampler2D _MainTex; fixed4 _LineColor; float _SplitCount; float _LineSize; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { return lerp( tex2D(_MainTex, i.uv), _LineColor, saturate( (frac(i.uv.x * (_SplitCount + _LineSize)) < _LineSize) + (frac(i.uv.y * (_SplitCount + _LineSize)) < _LineSize) ) ); } ENDCG } } }