GLSLでよく使う自作関数、マクロ

GLSLを書くときによく自作する関数やマクロのメモ。随時更新予定。

## PI, TAU

`PI`が円周率、`TAU`が円周率の2倍。

```glsl
#define PI 3.14159265359
#define TAU 6.28318530718
```

## palette

三角関数を使っていい感じのカラーパレットを作成できる関数。

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

マクロ関数版。

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

使い方(マクロ関数版)。

```glsl
vec3 c = palette(t, 0.5, 0.5, 1.0, vec3(0.0, 0.1, 0.2));
```

![palette.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/dc006ed4-5e7e-6dff-5de1-a87bbbf5f167.png)


詳しくは以下の記事を参照。

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

## remap

ある範囲の値を別の範囲に変換する関数。`[in0, in1]`の範囲の`t`を`[out0, out1]`の範囲に変換する。

```glsl
float remap(float x, float in0, float in1, float out0, float out1) {
    return out0 + (out1 - out0) * (x - in0) / (in1 - in0);
}
```

マクロ関数版。

```glsl
#define remap(x,in0,in1,out0,out1) ((out0)+((out1)-(out0))*((x)-(in0))/((in1)-(in0)))
```

## linearstep

`smoothstep`っぽい感じで2つの閾値の間を線形に補間する関数。

```glsl
float linearstep(float edge0, float edge1, float x) {
    return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
}
```

マクロ関数版。

```glsl
#define linearstep(edge0,edge1,x) (min(max(((x)-(edge0))/((edge1)-(edge0)),0.0),1.0))
```

使い方。

```glsl
float v = linearstep(0.3, 0.7, x);
```

![linearstep.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/a0bd2d54-db2f-0ca9-1443-5c63ca038e20.png)

詳しくは前に書いた記事を参照。

https://qiita.com/aa_debdeb/items/1165b98ec596ee20b519

## bumpstep

`step`関数で凸状に二値化する関数。

```glsl
float bumpstep(float edge0, float edge1, float x) {
    return step(edge0, x) * (1.0 - step(edge1, x));
}
```

マクロ関数版。

```glsl
#define bumpstep(edge0,edge1,x) (step((edge0),(x))*(1.0-step((edge1),(x))))
```

使い方。

```glsl
float v = bumpstep(0.3, 0.7, x);
```

![bumpstep.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/4d90c2c4-653f-b5e0-f8a4-464cdf6c9957.png)

## bumpsmoothstep

`bumpstep`の`smoothstep`版。

```glsl
float bumpsmoothstep(float edge0, float edge1, float edge2, float edge3, float x) {
    return smoothstep(edge0, edge1, x) * (1.0 - smoothstep(edge2, edge3, x));
}
```

マクロ関数版。

```glsl
#define bumpsmoothstep(edge0,edge1,edge2,edge3,x) (smoothstep((edge0),(edge1),(x))*(1.0-smoothstep((edge2),(edge3),(x))))
```

使い方。

```glsl
float v = bumpsmoothstep(0.2, 0.4, 0.6, 0.8, x);
```

![bumpsmoothstep.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/cce7b1c9-d9a8-191b-bef6-abf601754efb.png)


## decay

`x-==0`のとき1、`x`が大きくなるほど0に近い値を返し、いい感じの減衰を作れる関数。基本的には、`x>=0`の前提で使う。実際に使うときはわざわざ関数を定義しないけど。

```glsl
float decay(float x) {
    return exp(-x);
}
```

![decay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/7ffb3a35-fe65-168c-ee54-844071bb35f4.png)

## rotate

回転行列を生成する関数。

```glsl
mat2 rotate(float r) {
    float c = cos(r);
    float s = sin(r);
    return mat2(c, s, -s, c);
}
```

## blendScreen

[Screen合成](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AC%E3%83%B3%E3%83%89%E3%83%A2%E3%83%BC%E3%83%89#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%EF%BC%88Screen%EF%BC%89)をする関数。

```glsl
vec3 blendScreen(vec3 a, vec3 b) {
    return 1.0 - (1.0 - a) * (1.0 - b);
}
```

マクロ関数版。

```glsl
#define blendScreen(a,b) (1.0-(1.0-(a))*(1.0-(b)))
```

## random

乱数を返す関数。

```glsl
float random(vec2 x){
    return fract(sin(dot(x ,vec2(12.9898, 78.233))) * 43758.5453);
}
```