はじめに
Mental Ray 3.14 standalone で vMaterials(MDL マテリアル)の検証ステージを作る過程で、Final Gather(FG)特有の「まだら模様(blotch)」に悩まされました。indoor HDRI + FG というシンプルな構成の平面上に、雲のような濃淡ムラが浮かぶ現象です。
最終的に根本原因を数値で特定し、較正済みのステージ設定に着地しましたが、そこに至るまでに 5 つの勘違いを経由しました(5 つ目はこの記事の執筆中、裏取りの verbose ログで発覚したものです)。FG のパラメータは「どれを触っても見た目が変わる」ため、因果を取り違えやすいツマミの集合体です。同じ回り道をする方が減るように、勘違いの記録ごとまとめます。
検証環境: Windows / mentalray 3.14 standalone for Maya 2018 / 照明は室内 HDRI(mib_lookup_spherical + FG)のみ
勘違い 1: 「設定を増やしたらまだらが出た」
最初の観察はこうでした。
# これだとまだらが目立たない
finalgather on
finalgather scale 0.6 0.6 0.6 1.0
# Maya エクスポート由来の設定ブロックを足すと、まだらが出る
finalgather on
finalgather accuracy 100
finalgather scale 0.6 0.6 0.6 1.
finalgather secondary scale 1. 1. 1. 1.
finalgather rebuild on
finalgather filter 0
finalgather falloff 0. 0.
finalgather trace depth 1 1 0 2
finalgather presample density 1.
"finalgather mode" "automatic"
"finalgather points" 25
「設定を書き足したら劣化した」ように見えますが、因果が逆です。最小構成では、書かなかったパラメータはすべてレンダラーのデフォルト値で動きます。後日、最小構成に verbose 5 を付けて実測したデフォルトはこうでした。
option: finalg. mode 3.4
option: finalg. rays 1000
option: finalg. maxrad. 201.192
option: finalg. minrad. 20.1192
デフォルトの FG レイ数は 1000 本。Maya エクスポートの finalgather accuracy 100 は「デフォルトよりやや低い」どころか 1/10 への劣化でした。まだらが出て当然です。「設定が多いから壊れた」のではなく「良好なデフォルトを、わざわざ 1/10 の値で上書きした」のです。
DCC ツールがエクスポートする「全部入り options」を出自を確認せず流用すると、この種の事故が起きます。実際のデフォルト値は、最小構成に verbose 5 を付けてレンダリングし、ログの option: ダンプを読めば確認できます(このダンプが後述の勘違い 5 の発見にも繋がりました)。
勘違い 2: 「points を上げれば解決する」
まだらは "finalgather points" を 10 → 20 → 30 と上げると消えていきます。ここで「まだら対策 = points」と結論したくなりますが、points の実体はシェーディング時に平均する近傍 FG ポイントの数です。増やせばまだらは消えますが、それは壊れた値を大勢の平均に薄めている、つまりぼかして隠しているだけです。上げすぎればコーナーの暗がりや色の滲みといった間接光のディテールも一緒に失われます。
FG のノイズ制御は 3 段階のパイプラインとして役割分担を理解する必要がありました。
finalgather accuracy N は各 FG ポイントが半球に飛ばすレイの数で、発生源の分散を減らします。まだらの根本治療はまずここです(100 → 300)。"finalgather points" N は補間で均す段で、常識的な範囲は 25〜50。finalgather filter N は補間前に外れ値(スペックル)を統計的に棄却する段です。
正しい手順は「accuracy を先に確保 → filter を検討 → points は必要最小限」であり、points 単独で消すのは accuracy 不足の隠蔽になりがちです。
勘違い 3: 「filter はタダで効くノイズ除去」
そこで finalgather filter 1 を試したところ、まだらの様子が変わると同時に画面全体が暗くなりました。
これは filter の仕様どおりの挙動です。filter は「異常に明るい単発サンプル」を捨てますが、室内 HDRI の場合、その明るいサンプルの正体は多くが窓や照明器具に命中した正当なレイです。ノイズと一緒に本物の光エネルギーを捨てるため、全体が暗くなる。ノイズ除去とエネルギー忠実性のトレードオフであり、無料ではありませんでした。
今回のステージは「vMaterials の色が公式プレビューと一致するか」を検証する装置なので、エネルギー忠実性が生命線です。filter は 0(無効)を選択しました。
勘違い 4(未遂): 「暗くなった分は scale で補正すればいい」
filter で暗くなった分を finalgather scale を 0.6 → 0.8 に上げて補償する——一見合理的ですが、これは踏みとどまるべき操作でした。
この scale 0.6 は、公式プレビューと自前レンダリングが一致するように決めた較正定数です。ノイズ対策の都合でこれを動かすと、「プレビューと同じに見える」という検証全体の根拠が崩れます。基準器とノイズ対策のツマミは役割を分離し、較正定数は凍結する。もし照明条件(HDRI)を変えるなら、scale はその HDRI とのペアで較正を取り直す——という運用ルールに落ち着きました。
勘違い 5(執筆中に発覚): 「両者の差は accuracy だけ」
この記事の裏取りとして、最小構成と確定ステージ構成それぞれの verbose ログを突き合わせたところ、想定外の事実が出てきました。
| 項目 | 最小構成(デフォルト) | Maya ブロック由来 |
|---|---|---|
| FG モード | 3.4(レガシー) | automatic |
| FG レイ数 | 1000 | 100 |
| 収集半径 | シーン対角から自動導出(max 201 / min 20) | モード側で管理 |
| FG trace depth | 0 0 0 0(二次バウンスなし) | 1 1 0 2 |
"finalgather mode" を指定しない最小構成は、3.4 互換のレガシーアルゴリズム(シーンサイズから収集半径を自動導出する方式)で動いていました。一方 Maya ブロックは "automatic" モードを明示指定しており、FG ポイントの配置・補間のアルゴリズム自体が別物です。
つまり冒頭の「最小構成では出ない/ブロックを足すと出る」という比較は、accuracy の 1 変数比較のつもりが、実際にはモード・レイ数・半径・depth を含む多変数比較でした。1 変更 1 レンダリングの原則を説いてきた調査自身が、出発点で多変数比較の上に立っていた——というオチです。まだらの主因がレイ数(1000 → 100)にあることは accuracy 300 での改善から確かですが、「モード差の寄与」は厳密には分離できていません。切り分け結果を語るときは、暗黙のデフォルトも含めて何が変わったかを verbose で確認してから、という教訓になりました。
根本原因の特定: HDRI のピーク輝度を測る
対症療法を一巡した後、そもそも分散の発生源はどこかに立ち返りました。仮説は「室内 HDRI の高コントラスト構造(暗い壁 + 小さく極端に明るい窓)」。FG レイが窓に当たるか外すかでサンプル値が桁で暴れることが、まだらの正体ではないか。
これは測れば分かります。HDRI のピーク輝度を実測し、指定値でクランプした複製を作る Python スクリプトを書きました(OpenEXR 公式バインディング使用。opencv-python は手元のホイールが OpenEXR: NO ビルドだったため不採用)。
python exr_clamp.py small_empty_room_3_4k.exr 8
解像度: 4096x2048 チャンネル: ['R', 'G', 'B'] クランプ前ピーク輝度: 82.50
ピーク輝度 82.5。シーンの拡散照明レベルの数十倍のエネルギーが小さな窓に集中している、という仮説どおりの構造でした。
そしてクランプ版 HDRI(閾値 4 以上)でレンダリングすると、まだらは消えました。球の鏡面ハイライトも許容範囲。診断は確定です: まだらの根本原因は、FG のサンプリングが HDRI のピーク輝度を確率的にしか捉えられないことでした。accuracy や points は、この分散を試行回数と平均化で抑え込むための対症療法だった、と全体像が繋がります。
診断は確定、しかし治療は不採用
ここで判断が要ります。クランプは根本治療ですが、窓のエネルギーを削るため全体照度が下がり、凍結したはずの較正(scale 0.6 でプレビュー一致)が崩れます。クランプ版を採用するなら scale の再較正が必要になり、しかも「原本 HDRI に忠実」という検証ステージの趣旨からも一歩遠ざかる。
一方、accuracy 300 / points 30 の対症療法で、実用上まだらは十分抑えられていました。そこで今回は診断結果を文書化した上で、治療(クランプ)は不採用としました。原因が特定済みであれば、対症療法は「その場しのぎ」ではなく「トレードオフを理解した上での選択」になります。
なお、どうしても「まだらは消したいがハイライトは残したい」場合の上級手段として、FG が見る環境(クランプ版)と鏡面レイが見る環境(原本)を別シェーダーに分ける構成もあります。今回は単一 HDRI で足りたため見送りました。
確定したステージ設定
最終的に凍結した FG ブロックです。全行に実測の根拠があります。
finalgather on
finalgather accuracy 300 # 分散の主対策(100 では不足を確認)
finalgather filter 0 # エネルギー忠実性を優先(1 は暗くなることを確認)
"finalgather mode" "automatic" # points を使うモードであることを明示
"finalgather points" 30 # 補間は控えめ(60 はぼかしすぎ)
finalgather trace depth 1 1 0 2 # FG レイの二次バウンス(デフォルトは 0)
finalgather scale 0.6 0.6 0.6 1. # 較正定数として凍結(プレビュー一致の根拠)
意図通りに解釈されているかは verbose ログで確認済みです。
option: finalg. mode automatic
option: finalg. points 30
option: finalg. rays 300
option: finalg. depth reflection 1, refraction 1, diffuse 0, total 2
option: finalg. scale 0.6 0.6 0.6 1
なお "finalgather points" は automatic 系モードのパラメータなので、モード指定とセットで書いています。「書いた設定」と「レンダラーが実際に採用した設定」が一致していることの確認までがワンセット、というのが勘違い 5 からの教訓です。
説明できない行は書かない。書いた行は「なぜその値か」を実験で答えられる。最初に流用しかけた Maya エクスポートの全部入り options とは対極の、いわば全行説明可能な options です。
まとめ — FG まだら模様チェックリスト
-
まず最小構成 +
verbose 5でデフォルト値を確認する。 DCC 由来の options ブロックはデフォルトより低品質な値を含むことがある - まだら対策の第一手は accuracy(発生源の分散)、points は最後の微調整。 points だけで消すのはぼかしによる隠蔽
- filter はエネルギーを捨てる。 明るい光源が支配的なシーン(HDRI 照明)では全体が暗くなる副作用を織り込むこと。色検証用途では filter 0 が無難
- 較正定数(scale)とノイズ対策のツマミを混ぜない。 較正は照明条件とのペアで凍結する。
- 分散の発生源は測定できる。 HDRI のピーク輝度を実測し、クランプ版との比較レンダリングで因果を確定できる。診断と治療の採否は別の判断
-
切り分けは「暗黙のデフォルト」まで含めて 1 変数に。
"finalgather mode"を書くかどうかでアルゴリズム自体が切り替わる。書いた設定が実際に採用されたかは verbose の option ダンプで確認するまでがワンセット
FG のパラメータ調整は「簡単ではない」というのが正直な実感ですが、一度チューニングして凍結したステージは固定資産になります。数百のマテリアルを検証する間、この options には二度と触れない予定です。

関連記事
- 前回: Mental Ray 3.14 + MDL の bad texture エラーの正体は UV 欠落だった
- vMaterials の
_proto_mtl呼び出しパターン

