気分転換にパネル表示をいじってみる。とりあえず半透明のパネルを出していたのだが、もう少し工夫したいのですりガラス処理+角丸四角形にしてみた。
中身のデザインが今ひとつだけど、とりあえずパネル自体はこんな感じかな。すりガラスも角丸もシェーダーで実装。

すりガラス
すりガラスは一般的にはガウシアンブラーを使うらしい。ただ、普通に5×5とかのカーネルで処理すると重くなるので、縦5をかけた後に横5をかける、みたいに2パスでやるらしい。検索するとそういう方針でGrabPass(レンダリングされた画像を取得するやつ)を使用した例がたくさん出てくる。
ただ、Universal Render PipelineだとGrabPassがサポートされてなくて、同様の機能を持つCameraOpaqueTextureを使うと2パスができない(と思う)。なので、カーネルを省略して十字みたいな感じに近似してみた。上の画像の通りそれっぽくはなるからいいかな。
角丸四角形
角丸四角形はなかなか難しい。公式的にはRounded Rectangleっぽいんだけどそのままコピペしてもうまくいかない。なので参考にしながら自力で実装。
float RoundedRectangle(float2 uv, float width, float height)
{
// uvは-width/2~width/2、-height/2~height/2の座標
// uvから一番近い矩形状の座標を計算する
float2 pt = float2(min(abs(uv.x), width / 2 - _Radius), min(abs(uv.y), height / 2 - _Radius));
// 計算した矩形状の位置とuvとの差分ベクトルの長さを計算する
float d = length(pt - abs(uv));
// 半径以内なら1、半径よりおおきければ0
return smoothstep(d - _Radius / 10, d + _Radius / 10, _Radius);
}
fixed4 frag(v2f i) : SV_Target
{
// 角丸四角形判定。範囲内にあるならr=1、ないならr=0
float width = 1 / _CameraOpaqueTexture_TexelSize.x;
float height = 1 / _CameraOpaqueTexture_TexelSize.y;
float2 uv = float2((i.uv.x - 0.5) * width, (i.uv.y - 0.5) * height);
float r = RoundedRectangle(uv, width, height);
// 角丸四角形外(rが0に近い)は描画しない。
clip(r - 0.1);
・・・
ガウシアンフィルタ処理(他でたくさん紹介されているので省略)
・・・
// 角丸のα値:r
// オリジナルのα値:α
// オリジナル色:o
// ガウシアンフィルタをかけた背景色:b
// とすると、以下で表せる
// rα*o + (1-rα)*b
fixed4 col = r * _Color.a * _Color
+ (1 - r * _Color.a) * b;
return col;
}
こういうときに数学が役立つ。数学の知識がない場合、ぴったりうまくいくコードを見つけてコピペするかAssetを買うしかないので不利になる。