プロシージャルになんとなくおしゃれな感じのグラデーションを作る方法です。
Unity2019.1.10
やりたいこと
下記のサイトで、プロシージャルなグラフィックスを作るときにいい感じのカラーパレット作る方法が紹介されていました。
これによると、以下の式でカラーパレットが作れるようです。
ここでtは0~1の値で、これによりカラーパレットのどこから色を取るかが決まります。
a,b,c,dはそれぞれ三次元の値です。
cはRGBそれぞれの振動、dは位相のずれを表します。
つまりRGBのそれぞれの値について振動数の違うコサインカーブを作って、それらをちょっとずつずらして合成することで色を作ります。
また、グラデーションをループさせたい場合はcの値に整数を入れる必要があります。
aとbは最終的に明るさやコントラストを調整するだけの値なので、
今回は両方0.5の固定値で計算することにします。
ソースコード
それではこれでどんな感じのグラデーションが作れるのか試してみるためのソースコードを書いてみます。
using UnityEngine; public class Example : MonoBehaviour { [System.Serializable] public class OscilateTimes { public bool looping = true; [Range(0.0f, 10.0f)] public float r = 1.0f; [Range(0.0f, 10.0f)] public float g = 1.0f; [Range(0.0f, 10.0f)] public float b = 1.0f; } [System.Serializable] public class Phases { [Range(0.0f, 1.0f)] public float r; [Range(0.0f, 1.0f)] public float g; [Range(0.0f, 1.0f)] public float b; } [SerializeField] private OscilateTimes _oscilateTimes = new OscilateTimes(); [SerializeField] private Phases _phases = new Phases(); private Texture2D _texture; private void Awake() { _texture = new Texture2D(100, 1); } private void OnRenderImage(RenderTexture source, RenderTexture dest){ Graphics.Blit(_texture, dest); } private void Update() { // ループ設定の場合は振動数を整数にする if (_oscilateTimes.looping) { _oscilateTimes.r = Mathf.Round(_oscilateTimes.r); _oscilateTimes.g = Mathf.Round(_oscilateTimes.g); _oscilateTimes.b = Mathf.Round(_oscilateTimes.b); } // テクスチャを更新する for (int i = 0; i < 100; i++) { var rate = (float)i / 100; _texture.SetPixel(i, 0, GetColor(rate, _oscilateTimes, _phases)); } _texture.Apply(); } private Color GetColor(float rate, OscilateTimes oscilateTimes, Phases phases) { var r = 0.5f + 0.5f * Mathf.Cos(Mathf.PI * 2 * (oscilateTimes.r * rate + phases.r)); var g = 0.5f + 0.5f * Mathf.Cos(Mathf.PI * 2 * (oscilateTimes.g * rate + phases.g)); var b = 0.5f + 0.5f * Mathf.Cos(Mathf.PI * 2 * (oscilateTimes.b * rate + phases.b)); return new Color(r, g, b); } }
内容としては前節の計算で求めた色をテクスチャに焼き込み、
画面に対して描画命令を走らせているだけです。
色々と適当ですがまあ軽く試す分には十分でしょう。
結果
Inspectorからcとdの値を編集してなんとなくいい感じのグラデーションが作れるようになりました。
シェーダで使えば表現の幅が広がりそうです。