8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

uGUIのImageにGlowっぽい輪郭線を付けるスクリプトの改良

Last updated at Posted at 2020-10-11

初めに

UnityのuGUIのImageにOutlineスクリプトを適用すると、画像に輪郭線を付けることが出来るが、Glowの様なぼやけた輪郭線を付けるのは難しい。
対応策としてはこちらのコガネブログさんでも紹介されているが、以下のGlowImageというプロジェクト内にあるC#とShaderコードを使うという方法がある。
http://baba-s.hatenablog.com/entry/2017/12/31/211500
GlowImageのGithub
https://github.com/SylarLi/GlowImage

今回自分の勉強がてらこちらのコードを解読していた時に、「UnityのMask機能に対応していない事」と「シェーダーで最適化出来そうな所がある事」に気づいたので、改良してみた。

元コードのGlowImageで行っている事

箇条書きにすると以下のようになる
・Imageコンポーネントを継承したGlowImageクラスを作成
・GlowImageクラスのパラメーターから、既存Imageにアウトライン用の頂点とメッシュを追加する
・シェーダーでアウトラインを描画しつつガウシアン処理でぼかす
・最後に通常のImageを描画して行い終了

UnityのMask機能に対応させる

UnityのMask機能は、canvasRendererに登録されているマテリアルからマスク処理が適用されているコードを選別して処理を行っている。
既存コードではcanvasRendererに登録する処理が抜けていたため、canvasRendererをオーバーライドして、Image.materialにマテリアルを格納してからGraphicクラスのmaterialForRenderingを呼んで対応した

        public override Material materialForRendering
        {
            get
            {
                if(m_Material == null)
                {
                    material = new Material(Shader.Find("UI/GlowImageImprovement"));
                }
                // ここでパラメーター設定行う
                material.SetFloat("_OutlineSize", m_OutlineSize);
                material.SetColor("_OutlineColor", m_OutlineColor);
                material.SetFloat("_OutlineStrength", m_OutlineStrength);
                string format = "QUALITY_{0}";
                foreach (var item in System.Enum.GetNames(typeof(ImageOutlineQuality)))
                {
                    material.DisableKeyword(string.Format(format, item.ToUpper()));
                }
                material.EnableKeyword(string.Format(format, quality.ToString().ToUpper()));

                return base.materialForRendering;
            }
        }

ガウシアン処理の最適化

既存コードのシェーダーだと通常の平滑化処理のため重み(3x3, 7x7など)の数が増えるほど、ループ数が9, 49などかなり顕著に多くなっている。
画像処理のぼかし処理でよく使われるガウシアンブラーを使用する時、xとyの要素を切り離して処理できる場合ループ数を抑えることが出来る。
今回は以下のサイトを参考にコードを組んだ。

【Unity】【シェーダ】ガウス関数を使ってブラーを掛ける
http://light11.hatenadiary.com/entry/2018/05/20/010105
Unityでガウシアンブラーを実装する
http://edom18.hateblo.jp/entry/2018/12/30/171214

サンプルプロジェクト

コード全文は以下のプロジェクトを参照してください
※Windows10 + Unity2018.4.0f1で動作確認済み。
※ImageのTypeが「Simple」のみ対応
https://github.com/madoramu/GlowImageImprovement

実行結果
ss.png

補足

UnityのOutlineは頂点と頂点カラーを追加しているだけなので元画像も含めて1passで描画しているが、今回のコードはガウシアン処理の関係上2passで描画しなくてはいけないので、処理的には少し重いかも・・・

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?