palette関数でグラデーション

シェーダーで配色するときに、以下のようなpalette関数を使うといい感じのグラデーションを作ることができる。しかし、パラメータからどういうグラデーションができるか予測しづらいという欠点もある。この記事は、palette関数でパラメータを変えたときの挙動をメモ的にまとめたものである。

```glsl
vec3 palette(float t, vec3 offset, vec3 amplitude, vec3 frequency, vec3 phase) {
    return offset + amplitude * cos(6.28318530718 * (t * frequency + phase));

```
https://iquilezles.org/www/articles/palettes/palettes.htm

なお、この記事で出てくるコードは上述したpalette関数をマクロ関数にしたものを使用している。

```glsl
#define palette(t,offset,amplitude,frequency,phase) ((offset)+(amplitude)*cos(6.28318*((t)*(frequency)+(phase))))
```

---

まずはphase以外を固定して試してみる。

位相の差を等間隔にすると、虹色のグラデーションになる。

```glsl
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.333, 0.666))
```
![palette_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/e83d285d-8a35-5c25-e79d-d3dbf2210476.png)

---

RGBの位相差を等間隔なまま小さくすると、グラデーションに明るい部分(白色)と暗い部分(黒色)が表れる。

```glsl
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.2, 0.4))
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.1, 0.2))
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.05, 0.1))
```
![palette_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/6e57a449-0d7e-4659-4c0f-7d48f76dbcd8.png)
![palette_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/a7d1c290-acaf-f869-019f-eda871d3bc35.png)
![palette_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/a5c31b42-46bb-2188-4582-098d47570fde.png)

```glsl
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.4, 0.2))
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.2, 0.1))
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.1, 0.05))
```

![palette_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/951776bc-8a67-dd05-087a-f6f2585d89bf.png)
![palette_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/8635a1a8-0769-cbf7-fe06-f86be2f20388.png)
![palette_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/de431293-a069-6035-9a7d-0c5c2ad112d0.png)

```glsl
palette(t, 0.5, 0.5, 1.0, vec3(0.2, 0.4, 0.0))
palette(t, 0.5, 0.5, 1.0, vec3(0.1, 0.2, 0.0))
palette(t, 0.5, 0.5, 1.0, vec3(0.05, 0.1, 0.0))
```

![palette_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/595cbafe-969f-b225-1a10-3ce67fac4f99.png)
![palette_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/da11731b-a31b-ab0b-c997-e38c361524dd.png)
![palette_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/b8f77007-4a41-9cd5-fcbb-3ac997851928.png)

---

RGBのうち2つの位相差を小さくすると、2色のグラデーションのようになる。

```glsl
palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.1, 0.5))
palette(t, 0.5, 0.5, 1.0, vec3(0.5, 0.0, 0.1))
palette(t, 0.5, 0.5, 1.0, vec3(0.1, 0.5, 0.0))
```

![palette_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/22ff607a-32a9-23b3-bd61-d4d64ce96e92.png)
![palette_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/3a45ccd6-04eb-d0e2-88c4-d69f025a049c.png)
![paltte_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/e9eed6b9-177e-2178-9e0e-ad6c5cae37a4.png)

---

ここからはphase以外もいじってみる。

frequencyをいじると、いろいろな色が現れるようになるが制御が難しそう。

```glsl
palette(t, 0.5, 0.5, vec3(1.0, 2.0, 3.0), vec3(0.0, 0.333, 0.666))
```

![palette_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/b58ce301-626c-d437-5278-61d1b78c4089.png)

---

offsetとamplitudeもいじってみる。

例えば、R成分を定数にしてみるとこんな感じ。

```glsl
palette(t, vec3(0.0, 0.5, 0.5), vec3(0.0, 0.5, 0.5), 1.0, vec3(0.0, 0.0, 0.2))
palette(t, vec3(0.5, 0.5, 0.5), vec3(0.0, 0.5, 0.5), 1.0, vec3(0.0, 0.0, 0.2))
palette(t, vec3(1.0, 0.5, 0.5), vec3(0.0, 0.5, 0.5), 1.0, vec3(0.0, 0.0, 0.2))
```

![palette_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/1c5466d5-4dcf-ade0-bdf8-3fe5d16730d3.png)
![palette_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/87257550-ed73-524e-0033-82e48c2d7c46.png)
![palette_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/c54f031c-8a2d-777c-1c89-4802650a6bc8.png)

---

offset、amplitudeもいじるといい感じのグラデーションができるが、結局挙動を予想しながら作るのは難しい。

```glsl
palette(t, vec3(0.7, 0.5, 0.3), vec3(0.2, 0.3, 0.3), 1.0, vec3(0.0, 0.35, 0.5));
palette(t, vec3(0.4, 0.5, 0.5), vec3(0.2, 0.3, 0.2), vec3(2.0, 1.0, 1.0), vec3(0.0, 0.4, 0.5))
palette(t, vec3(0.2, 0.6, 0.4), vec3(0.1, 0.5, 0.1), vec3(1.0, 1.0, 2.0), vec3(0.0, 0.3, 0.15))
palette(t, vec3(0.5, 0.7, 0.5), vec3(0.5, 0.1, 0.5), 1.0, vec3(0.0, 0.5, 0.3))
```

![palette_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/3dc4aada-03d1-4694-1162-eef8a1eb4188.png)
![palette_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/ea917535-7889-f962-765a-b9a84af53afb.png)
![palette_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/663b34c6-dcc6-2048-12ed-4c414a5de88f.png)
![palette_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/982ebfda-2f9b-5c85-8390-0f0847138ddd.png)