CYBIRD Advent Calendar 2025の20日目担当、@cy-tatsuya-sakai です。
19日目は @gumita さんの「AIにお任せしてゲームを作ってみた」でした。
はじめに
今年の3月ごろ、Unity6のuGUIでシェーダーグラフが使える & サンプル出たと記事になっていましたね、これはありがたい!
https://gamemakers.jp/article/2025_03_14_95059/
今回はこのUGUI Shadersサンプルを使ったシェーダーグラフでお手軽に、ボタンやモーダル等に使える
・角丸
・角丸以外
を描画してみようと思います!
記事の説明にはUnity6000.2.15f1、Universal 2Dコアテンプレートから作成したUnityプロジェクトを使用します。
下準備
UGUI Shadersサンプルのインポート
https://discussions.unity.com/t/announcing-the-shader-graph-ugui-shaders-sample/1602836
サンプルのインポートはパッケージマネージャーから。

Subgraphsフォルダ以下に便利なサブグラフが入っていて、

SubgraphLibrary.shadergraphでサブグラフを一覧できます。すごい!

9スライス用スプライトの準備
サンプルではスプライトを使用していないみたいでしたが、今回は普通にスプライトを使用します。
9スライス出来れば良いので、適当な極小テクスチャをスライスします。
今回は4x4のテクスチャを、中心でスライスしてみました。
Pixels Per Unitがテクスチャサイズと一致していれば何でもOKです。


シェーダーグラフの作成
ProjectビューからCreate > Shader Graph > URP > Canvas Shader Graphでシェーダーグラフを作成します。
uGUIのImageコンポーネントに先ほどのスプライトと、作成したシェーダーグラフのマテリアルを設定すれば準備完了です![]()

角丸の描画
Rectangleサブグラフ
サンプルのSDFs/RectangleノードをAlphaに繋げば、完成!


既存のShapes/Rounded Rectangleよりパラメータ豊富で、細かな調整ができます。
Edge Min, Edge Max
角丸の境界を滑らかに出来ます。擬似的なアンチエイリアス効果もありそう。

Corner Radii
四隅それぞれに丸さを設定できます。ヘッダーやバッジ・リボン的な表現に使えそうです。

Stroke
SDF, SDFStoroke
角丸描画に使われた生のSigned Distance Fields(SDF)。何かに使えるかもしれない。
角丸サイズを個々に調節する
角丸サイズはシェーダーのCorner Raddiで調節するほか、ImageコンポーネントのPixels Per Unit Multiplierでも個々に調節できます。
もし角丸サイズ = 1Unitサイズにしたい場合は、Canvas ScalerのReference Pixels Per Unitの値をRectTransformのWidthないしHeightで割ればOKです。

大抵の場合Reference Pixels Per Unitはデフォルトの100になっていると思うので、
単純に100 / (RectTransform.Width or Height)と計算式をそのままPixels Per Unit Multiplierに入力すれば良いと思います。
Pixel Per Unit Multiplier = 100 / RectTransform.Height

角丸はSDF描画なのでジャギーは発生せず、綺麗に丸さを変えられています。グッド!
見た目のバリエーションを考える
フラットな見た目を変えてみます。
陰影を付ける
陰影を付けて立体感を出してみます。
法線を使って陰影計算
(Normal From HeightノードはCanvasのAdditional Shader ChannelsでNormal, Tangentにチェックを入れないと動作しなさそうだったので注意)



影色を変える
影を黒ではなく、任意の色にするとUIの印象を変えられるかも?

もしImageカラーそのまま描画 & マテリアル共通にするなら、影色は頂点カラーをHSV形式でオフセットした値にすると、色違いのUI間で影色の印象を揃えられる気がしなくもないです。

線形グラデーションに、彩度MAX・色相ずらして影色にするとこんな感じ。
明るい印象になったでしょうか?

UI全体にグラデーションを付ける
BaseMeshEffectを継承したスクリプトで頂点情報を追加できます。
例えばUV2に9スライスしていない状態のUVを書き込めば、UI全体にグラデーションを付けることも可能です。
UV2をシェーダー側で読み取るために、CanvasのAdditional Shader ChannelsでTexCoord2のチェックを忘れずに。
ちなみにUV1は書き込んでも反映されませんでした。謎。
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// UIのUV2に0〜1を設定
/// </summary>
public class NormalizedUV2 : BaseMeshEffect
{
public override void ModifyMesh(VertexHelper vh)
{
if(vh.currentVertCount <= 0)
{
return;
}
UIVertex vert = new();
Vector2 min;
Vector2 max;
{
vh.PopulateUIVertex(ref vert, 0);
min = max = vert.position;
}
// 頂点座標の最小、最大を計算
for(int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vert, i);
min.x = Mathf.Min(min.x, vert.position.x);
min.y = Mathf.Min(min.y, vert.position.y);
max.x = Mathf.Max(max.x, vert.position.x);
max.y = Mathf.Max(max.y, vert.position.y);
}
if(max.x - min.x < 0.0001f || max.y - min.y < 0.0001f)
{
return;
}
// 頂点座標の0〜1を計算
for(int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vert, i);
var uv = new Vector2(vert.position.x, vert.position.y);
vert.uv2 = (uv - min) / (max - min);
vh.SetUIVertex(vert, i);
}
}
}
作成したスクリプトをImageのオブジェクトにアタッチして、シェーダー側でUV2を参照するとこんな感じ。どうでしょう?



角丸以外を描画する
角丸以外の形状にしたい!
Rounded Cornersサブグラフ
角丸の丸さを決めていたCorner Raddiの内部処理は、それ単体でRounded Cornersサブグラフ化されていました。

これを任意のSDFに乗算すれば、角丸以外の形状も作れそうです。
先人の知恵をお借りして、適当なSDFを作ってみます。
https://qiita.com/7CIT/items/fe33b9b341b9918b6c3d
こんな感じ!…見た目の良し悪しはさておき、一応角丸以外も作れました。

おわりに
uGUIで気軽にシェーダー作れるのは素直に嬉しい!SDFで綺麗に描画できるのもポイント高いです。
この記事は地味目でしたが、UGUI Shadersサンプルにはもっと格好良い実装例もあるので、そちらもぜひチェックしてみて下さい!
明日のCYBIRD Advent Calendar 2025 21日目は、@moffunnya さんの「誰でも使えるログ調査環境についての感想(クラスメソッド様主催 ゲームクリエイターズキャンプ)」です。お楽しみに!









