This explanation is currently available in Japanese.
ひとことで
近い所に同じような値が固まらないよう、細かい粒がまんべんなく散らばった乱数です。ふつうの乱数(白色雑音)は、たまたま大きい値が並んだり、小さい値が並んだりして、目に見える「むら」ができます。ブルーノイズは、周波数で見ると低い周波数(大きなむら)の成分がほとんどなく、高い周波数(細かい粒)だけでできています。人の目は細かい粒には鈍く、大きなむらには敏感なので、同じ量のノイズでもずっと目立たなくなります。
ゲームでの使いどころ
- ディザ(減色・半透明):少ない色数でグラデーションを表すときや、遠くの物体を点状に抜いて半透明に見せる(ディザ透明)ときの、しきい値の表。
- レイマーチの開始位置のずらし:ボリュームのレイマーチや影で、歩幅による縞をなくすために開始位置をずらす。白色雑音よりざらつきが細かい。
- 少ない標本での効果:SSAO、ソフトシャドウ、反射などで、1 画素あたり数本しか光線を飛ばせないときの乱数。
- 時空間ブルーノイズ:フレームごとに値をずらし、TAA で時間方向に平均すると、少ないフレーム数で正しい値に近づく。空間だけでなく時間方向の偏りも抑えた表(STBN)も使われる。
しくみ
ゲームでは、あらかじめ作ったブルーノイズの表(64 × 64 や 128 × 128 の画像)をくり返し並べて使うのが一般的です。表の作り方の代表が、ボイド・アンド・クラスター法(Ulichney 1993)です。
- 混み具合を測る:点のある場所にガウス関数(ぼかし)を置いて足し合わせ、各場所の「混み具合」を求めます。端は反対側とつながっているものとして計算するので、表をくり返し並べても継ぎ目が出ません。
- 最初の点を整える:でたらめに少し点を置き、最も混んだ点を最もすいた場所(ボイド)へ動かすことを、動かなくなるまでくり返します。
- 順位を付ける:すいた場所に 1 点ずつ置いていき、置いた順番を順位として記録します。すべての場所に順位が付いたら、順位を 0〜1 に直して表にします。
どの順位で切っても、そこまでの点が均等に散らばっているので、しきい値をいくつにしても均一なディザになります。
実装のポイント
- 表は画面の座標で引く:ワールド座標ではなく、画素の位置で引くと、粒が画面上で均一になります。
- 補間しない:表をなめらかに補間すると、粒がぼけて性質が崩れます。最近傍で読みます。
- 複数の値が必要なとき:同じ表をずらして読むと値どうしが似てしまいます。RGBA の各チャンネルに別々の表を入れるか、ずらし量を大きく取ります。
- 自分で作るより配布物を使う:質の良いブルーノイズの表は、研究者やエンジンの配布しているものが使えます。作るのは時間がかかるので、事前に作って画像として持ちます。
つまずきやすい点
- 表のくり返しが見える:小さすぎる表をくり返すと、周期が見えます。64 × 64 以上を使い、必要なら表の読み出し位置をフレームごとにずらします。
- ガンマの扱い:表の画像を sRGB として読むと値がゆがみます。線形の値として読みます。
- ノイズの量が減るわけではない:誤差の総量は白色雑音と同じくらいで、分布を目立たない形に変えているだけです。消すにはTAAやぼかしを組み合わせます。
デモで試すこと
- 「乱数の表そのもの」で、左の白色雑音にはむら(固まりとすき間)があり、右のブルーノイズは粒がそろっていることを比べてください。
- 「グラデーションのディザ」では、同じ白黒 2 値でも、ブルーノイズの方が少し離れて見るとなめらかです。
- 「周波数」では、ブルーノイズの中心(低い周波数)が暗く抜けていることがわかります。
- 「時間方向に平均」では、右下のグラフで、ブルーノイズの誤差の方が速く小さくなります。「しきい値」を変えても、ブルーノイズは均一なままです。