某所でアンチエイリアスの話をしていて。
実践的なアンチエイリアスの設定方法。
意外と知られてないっぽかったので、ここで解説を試みる。
技術的には多少間違っている所もあるかも知れない。
まあ実用レベルで支障がない程度の正しさはあるでしょう。たぶん。
●前置き
そもそもアンチエイリアスとはなんぞや。
アンチエイリアスとは、エイリアシング(主にジャギー)を軽減するための処理のこと。
ではエイリアシングとはどういう時に起こるのか。
近接するピクセル間のコントラストが高い(輝度差が高い)時に起こる。
解像度が低い場合もエッジを形成するピクセル数が十分でないため起こりやすい。
解像度は変えずにジャギーを軽減するにはどうすればいいのか。
基本的にはコントラストを下げてやれば良い。
コントラストを下げるにはどうすればいいのか。
そのピクセルの色を平均化して行けば良い。
簡単に言えば、ボカせば良い。
こうすることによって、ジャギー=ギザギザの軽減だけでなく、
・ポップイン/アウト=ちらつき
(アニメーションのあるシークエンスで、小さなディテールがフレームによって見えたり見えなかったりすること)
・モアレ(規則正しい繰り返し模様がある部分などで、縞模様になること)
の軽減にもなる。
●実際の処理
XSI(っていうより MentalRayか)は、アダプティブスーパーサンプリングっていうのかな、Adaptive、つまり必要に応じて、必要なだけのサンプリングをする仕組みのアンチエイリアスを行います。無駄に重いことをせずに済むよう、必要かどうかをピクセルごとにチェックして、必要ならばさらにサンプリングの分割数を上げる、という仕組みです。
いじるべきパラメータは、Mental Ray オプションの、
Min Level -- 1ピクセルあたりの、最小のサンプリング分割回数
Max Level -- 1ピクセルあたりの、最大のサンプリング分割回数
Sampling Contrast -- 次のサンプリング分割に移行するかどうかのしきい値
この3つ。 Min と Max は、「分割数」ではなく、「分割回数」であることに注意して下さい。
例えばこれが、
Min 0
Max 2
SC 0.2
となっていた場合、
最低でも0回は分割しろ(=つまりこの場合、分割しない)
0.2 以上のコントラスト差があったら、ボカせ。
それでもダメなら、もう1回分割して、また同じことしろ。
でも2回分割したらそれでやめろ。重いから3回目の分割はすんじゃねえぞゴルァ。
と言っていることになります。
一応、どういう処理がされるのかを順番に書きます。
1:あるピクセルについて、隣接するピクセルとのコントラストを調べる
2:コントラストが 0.2 以下だった場合 → そのピクセルには何もせず1へ(次のピクセルへ)
:コントラストが 0.2 以上だった場合 → ボカしてコントラスト下げる
3:もう1回コントラスト調べる
4:0.2以下になった場合 → アンチエイリアス終了、次のピクセルへ
:まだ 0.2 以上だった場合 → ボカし、それでもダメならそのピクセルを縦横2分割する(4つの小さいサブピクセルに分割)
5:分割されたサブピクセル1つ1つについて、またコントラスト調べる
6:0.2 以上ならさらにボカし、それでもダメならさらに分割する(元から数えて4分割=16サブピクセル)
7:それでもまだ 0.2以上だった場合でも、Max = 2(分割最大回数2)に達したので、もう分割しない
ということをやっています。たぶん。ボカしと分割の順序あたりはかなり怪しいけど。詳しい方、間違っていたら指摘してください。生ビール(約500ml)進呈を検討します。
SCを 0.2 としているということは、いわば輝度差が 0.2以上あればそれはエイリアシングだ、だからボカせ、と言っているようなもんだと思ってもいいと思います。最大回数まで達しても 0.2以下にならなかった場合、エイリアシングが発生してるということです(0.2 をエイリアシングと見なした場合のエイリアシング)。
●調整方法
実際の調整方法(順序)を書いてみます。
1:SCを下げる
ある程度以上細かい模様のある画像の場合、SC をそれなりに低くしないとどうしてもエイリアシングが発生します。なのでまず、SC をちょっと下げます。判定基準を厳しくするということです。判定基準が甘いままだと必要な部分が次の分割に進んでくれないからです。はなからジャギーが発生しにくいような絵の場合は、SC は高い数値のままで Max とかいじり始めてもいいかもしれません。SC も高い数値(甘い判定基準)で済めばそれに越したことはないわけですから。
2:Max を上げる
1だけではまだエイリアシングが発生している場合、Max をちょっと上げます。
3:Min を上げる
それでもダメな場合、Min をちょっと上げます(あらかさまに必要ない場合を除く)。
という順番が良いかと思います。
Minを上げるということは、1ピクセルの最低分割回数を上げるということなので、たとえ必要のない(SC のコントラスト以下におさまってる)ピクセルでも、有無を言わさず分割するということです。画面全に細かいディテールがある場合などはいいかもしれませんが、そうでない場合は無駄です。だから Max を先に上げて、必要なエリアだけ Max の回数に向けて分割が進行するようにします。Min は最後です。
Min と Max が同じ数字の場合は、アダブティブサンプリングをしていないことになります。例えば Min=1 Max=1 の場合、SC の値に関係なく、全ピクセルを1分割することになります。Max も1なのでそれ以上の分割は起こらず、全ピクセル平等に1分割で終了します。結果的に、倍の解像度の画像を min=0 max=0 でレンダリングしたのと同じことになります。たぶん。
分割回数がマイナスの時は、分割と逆のことをします。つまり隣接したピクセル同士を結合させて、でかいピクセルとしてサンプリングします。サンプリングする回数が減るので当然軽くなります。min=-1 とした場合、最初は隣接するピクセルをつなげて大雑把に計算するわけです。ピクセルを1個おき(1個飛ばし)でコントラストを調べると考えてもいいと思います。-2 なら2個飛ばしです。この大雑把な計算で SC の値におさまっていれば次の分割が発生しなくて済むので、軽くなるわけです。
例えば、複雑な模様の部分もあるけど、コンスタントシェーダで単色な部分もある、というような画像をレンダリングするとき、単色部分はコントラスト0なので、 -2 や -1 でも十分なわけです。複雑な部分はそれではダメなので、Max を上げておけばその部分だけ分割が進行してアンチエイリアスしてくれます。Min を 1 とかにした日にゃあ、単色だろうが短小だろうが早漏だろうが、有無を言わさず必ず1分割するので、超無駄に重くしていることになります。上記の「あからさまに必要ない場合」というのがこれです。
ただし、そんなにディテールが細かいわけではなくとも、アニメーションしている場合、特にゆっくり動いている場合は、ピクセルがサンプルの間に入り込みやすいので、そのフレームではそのピクセルが消えてしまいます。次のフレームではまた突然現れたり。これがチラツキ(=ポッピング)です。こういう場合はある程度 Min も上げておかねばならない時があるかもしれません。
●サンプリングを視覚的に見る方法
わかりやすくするために、シンプルなシーンで実験します。新規シーンにプリミティブの球体を取り出して、そのまま何もいじらず、レンダーリジョンを描いてみましょう。
次にRender Region Options の Diagnostics タブで、View Sampling をオンにします。
この状態でリジョンを再描画してみましょう。
↑グリッド状の絵がレンダリングされます。この点の1つ1つがサンプルポイントです。新規シーンでのデフォルト設定は、 Min=-3 Max=-1 SC = 0.3 です。球体の、のっぺりした色の部分と輝度差が大きい部分で、点の密度が違うのがわかると思います。つまり輝度差の大きい部分だけ分割が進行しているわけです。無駄なくエコなレンダリングをしています。
ためしにこの状態で View Sampling をオフにして通常のレンダリングを見てみると、
↑エッジは汚いですが、暗い側の付近はそれほど汚くありません。つまりここら辺は、大してサンプリング分割が要らないはずだということです。
次に View Sampling をオンに戻して、Min と Max を上げてみましょう。
↑ -1,0とかにするとこのように、のっぺりしてようが輝度差があろうが、同じような点の密度になっています。Min =つまり最低分割回数を上げているので、画像全域で有無を言わさず分割されているわけです。本当に必要なのはエッジ付近だけなのに。実に環境に悪いレンダリングです。
●調整練習
さきほどの、一番最初の状態、つまり新規シーンのデフォルトの状態の絵をもう一度見てみましょう。
↑エッジが汚いのはもちろんですが、明るい側に変な水平線のようなアーティファクトが出ているのでこれも修正しなければいけません(矢印部分)。
まず、SC を下げていきます。
↑0.05 くらいまで下げたら、アーティファクトが消えました。
View Samplingモードでも見比べてみましょう。
SC が甘かった頃には分割が進まなかったエリアも、。SC を下げる=判定基準を厳しくしたので次の分割レベルまで進んだことになります。
次に Max を上げます。
↑ほぼジャギーを撲滅させるには、この場合 2 くらいでした。しかし、水平や垂直に近いエッジはまだ若干ジャギっています(白い矢印部分)。理論的には、画像がドットの集まりである以上当然、水平・垂直に近い部分が一番エイリアシングが起こりやすいわけです。45度の線が一番起こりにくいです。あ、もちろん正方形ピクセルの場合ですが。
で、Min を上げてみます。
↑ -1 くらいにしたら、水平・垂直に近い部分もだいたいジャギーが消えました。
ってことでこの画像は、Min=-1 Max=2 SC=0.05 くらいがちょうど良かろうということになりました。これ以上数値を上げても重くなるだけであんまり変わりません。
ためしに Max は 2 のままで、Min を 1 くらいまで上げてみてください。画像はほとんど変わらないのに、あからさまにレンダリングが遅くなったのがわかると思います。渋滞でスピードが出せないことがわかっている首都高を、燃費の悪い昔のアメ車で走るようなものです。環境破壊です。反省して下さい。
以上のようにして設定すると、無駄が少ないアンチエイリアスができると思います。実際、仕事ではこの Min=-1 Max=2 SC=0.05 付近の設定でいつもやってます(SD解像度の場合)。 HD だと解像度がでかいので、エッジを構成するピクセル数が多い分だけエイリアシングが起こりにくくなり、その分アンチエイリアスの設定を低くできる気がするんですが、HD の仕事が少ないこともあり、ちゃんとは実験していません。誰か実験して下さい。
スヴァらしい解説が↓ここにあります。
http://www.lamrug.org/resources/samplestips.html
自分もこれ(の、古いバージョン)で仕組みを覚えました。
当記事に間違いがあったら、コメントして下さい。自分もちゃんと理解したいのです。もし参考になったら、やはり何かコメント頂ければ、いや、生ビール(約500ml)をおごって頂ければと思います。
続く。かもしれません。続かないかもしれません。
最近のコメント