ポストエフェクトクエスト - スターバースト -

#初めに
かなり久々に記事を書きます．今回はよりまともな見た目のスターバースト(光条・光芒とも)についてになります．だからと言ってそこまで新しい知識などは不要です．復習もかねてやっていきます．
同機はただ[以前](https://qiita.com/AngularSpectrumMTD/items/77f71b24b21cbc3d2a52)実装したスターバーストの見た目があまり気に食わなかったからです．

#光条？光芒？
どちらも同じ意味ではあるようなのですが，どちらかというと今回のスターバーストは「光条」となるようで，「光芒」はゴッドレイのようなものを指すことが多いようです．
また，下図のように光条はレンズゴーストとともに観測されることが多いです．
ゴーストのポストエフェクトクエストも作成してはいますがいかんせん気に入らないのでそれはまた今度…L(^o^)Γ===333
特に深い意味はありませんがこの画像を作成する際に使ったカメラの絞りの開口部分は八角形と推測されます．
絞りの開口部分の形状が$n$角形の場合

```math
\text{光源中心から伸びる光線の本数} = \left\{
\begin{array}{ll}
2n & (n:奇数) \\
n & (n:偶数)
\end{array}
\right.
```

となるからです．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/c97786ba-58e2-e56c-1f59-e5ac665df6ec.jpeg" width=80%>


#簡単カメラ解説！！！
すごーーーく簡単化して描けば以下のようになります．カメラに飛んできた光は，絞りによって遮られその光量を低下させ，レンズによる回折でイメージセンサ上に集光され像を結びます．[以前の記事](https://qiita.com/AngularSpectrumMTD/items/77f71b24b21cbc3d2a52)では，フラウンホーファー回折とともに説明しました．「レンズによって集光された光の分布は，レンズに入る直前の光波分布のフーリエ変換像で与えられる」というものです．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/bc2fd124-35c1-e51a-9472-8ccd7fa0c290.png" width=80%>


#そもそも集光するまでの光の変化ってどんなの？？？
わりと波動光学の記事を書いては来ましたが，伝搬したときの変化を掲載したことがそんなにないなと思いましたので，ここらで一つgifを載せておきます．絞りで遮られた光が，レンズによって集光するまでの過程を示しています．
なおこちらの計算は「[角スペクトル法](https://qiita.com/AngularSpectrumMTD/items/429a0959bed08933851f)」で計算しています．非常に優れた回折伝搬計算手法です．(＊今回のポストエフェクトでは全く使いません)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/62fbc62f-8764-b4af-ef91-2e9cd7f175c7.gif" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/74ff6b9d-ba36-1093-f7ac-8413c952ff82.png" width=50%>
さてどうでしょうか．集光位置で何か見えませんでしょうか．
そうです．これこそがスターバースト(右図)です．

#絞りってどんな感じ？？？
下図のように，多数の羽根で構成された機構です．光の量を調節できます．絞り中心部の開口は絞るほどに多角形形状に近づきます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/b3eea70d-1cce-049e-d265-e1056d7c0756.png" width=100%>
絞るほど正多角形に，絞らないほど円形になりますから，正多角形とその外接円の中間の図形が主な開口の形状といえるでしょう．下図(左)でいうところの黒い太線で描かれた形状です．実装した結果は下図(右)のようになります．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/959b7f12-5c3b-fef1-69f4-8d149b4d1dcd.png" width=40%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/92d79459-8fff-e23d-9478-25f183fe0695.gif" width=40%>

<details>
<summary>絞り描画シェーダコード</summary>
<div>

```
struct ComputeParameters
{
	int N;//描画する絞りが作る開口部分は正N角形
	float r;//で半径がrであるとする
};

ConstantBuffer<ComputeParameters> computeConstants : register(b0);
RWTexture2D<float4> destinationImage: register(u0);

//WIDTH HEIGHTは描画するテクスチャの横縦サイズです

[numthreads(WIDTH, 1, 1)]//computeConstants.N角形
void DrawApertureBlades(uint3 dispatchID : SV_DispatchThreadID)
{
	float2 index = dispatchID.xy;
	float2 size = float2(WIDTH, HEIGHT);
	float2 uv = index / size - float2(0.5, 0.5);

	//判定したい点の位置
	float pos = length(uv);

	//判定したい点のなす角
	float rad = atan2(uv.x, uv.y) + 2.0 * PI;
	rad = rad % (2.0 * PI / computeConstants.N);

	float r_circ = 0.5 * computeConstants.r;

	//半径r_circの円に内接する正多角形の辺の位置
	float r_polygon = cos(PI / computeConstants.N) / cos(PI / computeConstants.N - rad);
	r_polygon *= r_circ;

	//円と多角形の中間(半径を大きくするほど=絞らないほど円形に近づく computeConstants.rは0～1)
	//lerp(x,y,s) = x + s(y - x)
	float s = computeConstants.r;
	float r_aperture = lerp(r_polygon, r_circ, s * s * s);

	//判定される点が描きたい多角形の内外かを判定
	float col = step(pos, r_aperture);

	destinationImage[index] = float4(col, col, col, 1.0);
}
```
</div>
</details>

#バーストはどう変化する？
冒頭でも説明しましたが，焦点位置でイメージセンサに光が当たるとするならばバーストは絞り開口画像のフーリエ変換像として与えられます．
以下は左の絞り開口により得られるバーストを右に示したものです．
![5角.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/c259ea2f-fff1-eca4-f881-43536b066391.gif)
![6角.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/4d7526ab-9a7e-3b45-ef94-67039b932628.gif)

#実際のバーストとの比較
冒頭の画像との比較です．勿論八角形の絞り開口のバーストと比較しています．(回転しています)
![比較.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/f929a84f-d8be-4796-5a53-0d2cc72ee300.png)

#ポストエフェクトとして使用する
今回もこちらの画像を使っていきます．
![gaitou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/be566d21-0e55-1865-4e82-cf8ae36d66f7.png)
「どうポストエフェクトをかけるのか」や「FFTのシェーダコード」などについても[以前の記事](https://qiita.com/AngularSpectrumMTD/items/77f71b24b21cbc3d2a52)をご確認ください．
ポストエフェクトをどうかけるのかについて説明した画像だけ流用しておきます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/57676187-dc8d-5e6b-edd6-633e02a4d66d.png" width=90%>

結果はこんな感じです．
![使用例.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/3c69d5fb-f813-ecaf-e553-55b132471f31.gif)

パラメタの違いもありますが以前実装した光芒エフェクト使用結果との比較はこちらになります．左が以前のもの，右が今回のものです．
なんとなくより「ありそうな」見た目になったように思います．やったね！！
![比較2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697216/05aa74d3-ffc6-3739-3c3d-2767ef72b5eb.png)


#おわりに
お疲れさまでした．また次のネタを考えておきます．
それでは～．