約 2 年前、UE4 AnswerHub でマテリアルにクロマキー (またはグリーン スクリーン) の設定方法に関する質問が投稿されました。それがきっかけで私は基本的なクロマキー機能 Chroma Key Alpha のモックアップを作ってみました。そしてそれが先日 UE4 に追加されました。クロマキー機能はリリースノートに含まれていますが、ご存じの通り、リリースノートは膨大ですべて読むのは大変です。当面使う予定がない機能は、詳細を読み飛ばしてそのまま忘れてしまいがちです。
新しいツールとデバイスが常時サポートされるようになり AR が勢いを増しています。これを裏付けるように、UE4 は最近 ARKit と ARCore をサポートしました。WWDC に関する Tim Sweeney の投稿をはじめ、面白いプロジェクトの記事を こちらで紹介しています。
このような動きに合わせて、UE4 でのクロマキー マテリアルの設定方法をブログで紹介することにしました。ほとんどの AR デモはライブ動画上でデジタル オブジェクトを合成しますが、中にはデジタル シーンへライブで被写体を投影するなど、複合現実を必要とするプロジェクトもあります。その場合、通常グリーン スクリーンを設定します。アルファがビルトインされていないので、これは少々難しいかもしれません。
グリーン スクリーンからアルファを抽出するこの処理をを「クロマキー」といいます。エピックは最近、Composure という名前の UE4 プラグインを追加しました。これにより、ポストプロセス処理とレンダリング要素を混ぜやすくなりました。ライブのクロマキー マテリアルを試す際にはうってつけというわけです。
最初にお伝えしておきたいことは、クロマキーを使って質の高い結果を出すことは難しいです。ほとんどの場合、複数の技術を組み合わせて使う必要があります。Nuke を始め、多くのソフトウェア パッケージは最新のメソッドを提供しています。Nuke が高品質のクロマキー アルファ抽出のために行っているほとんどの演算処理は、負荷が高いです。生放送など特定のプロジェクトでは、負荷の高い専門のハードウェア ソリューションを使う傾向があります。
そこで、ここで使うリアルタイム版はそれらと比べて本当に基本中の基本的機能だと考えてください。見た目の合格基準を満たすには、そのコンテンツに応じてかなりの微調整が必要になります。そうではありますが、エディタでとても簡単にクロマキーをプレビジュアル化し、テストが可能な値にできるので非常に便利です。
基本的な手法
クロマキーの背後にある考え方は、色を比較するマスクを作成して、そこからアルファ マスクを生成することです。2 つ目のマスクは、緑色のキャストをオブジェクトからデスピル (除去) するために使用します。通常デスピル マスクは、ソフトな、アルファ マスクの結果の反転バージョンになります。そして、そのデスピル マスクを使用して、緑色のキャストを統合先の背景に一致する色に置き換えて、フェイクの背景ライティングに追加します。
シンプルなステップですから、簡単に行う方法はいくらでもあります。私が初めて作ったバージョンは本当に基本的なものです。しばらくの間 UE4 に実装されています。これが前述した クロマキー アルファです。こちらが基本的な使用例です。
画像の色、クロマの色、アルファおよびデスピル マスクに対するいくつかの入力を受け取ります。このノードを使用したサンプルだけではなくて、最初よりも少し設定を改善したバージョン、そして関数内で実行されるステップを説明します。
色の抽出
色比較を生成するために最初に行うことは、グリーン スクリーン上でのわずかなシャドウとシワ、あるいはライティング グラディエントが邪魔にならないように、画像からルミナンスを取り除くことです。この関数の初回バージョンでは、単純に色の標準化だけを行いました。かなりきれいに取り除くことができましたが、エッジにアーティファクトが生じます。
明るさは、成分の合計で割っても取り除くことができます。均一できれいなトーンになりますが、境界付近が黒浮きするハロ アーティファクトが生じやすくなります。Photoshop でカラーレイヤーを使ってもこのようなエッジ アーティファクトが発生しないことが分かったので、方法をいろいろ考えてみました。
その答えは、ルミナンス ベースのサチュレーションの使用でした。これによりサチュレートした非常に暗いピクセルがカラーマップ内でサチュレートすることを防ぎます。結局のところ、サチュレートした暗いエッジ ピクセルは、双三次テクスチャのサイズ変更が原因だと分かりました。
このテスト画像は TV ショー 『Lost in Time』のものです。レンダリング シーンに UE4 を 使っています 。ちなみに、このテスト画像は高品質のそのままの画像ではなく、 低品質になるように圧縮された jpeg ファイルです。
ルミナスに基づいた彩度マップを生成するには、まず画像の彩度を減らして、シンプルな指数関数 e ^ -x を使ってルミナンス カーブを生成します。ルミナンス値 x は、ルミナンス マスクの強度を定義するパラメータによってスケールされます。1 は適切なデフォルト、0 にすると合計を割った数値そのものが結果になるようにノーマライズします。コードはこうなります。
float3 ExtractColor(float3 Color, float LumaMask)
{ float Luma = dot(Color, 1); float ColorMask = exp(-Luma * 2 * PI / LumaMask); Color = lerp( Color, Luma, ColorMask); return Color / (dot(Color, 2)); }
カラーマップを抽出したら、次は比較をしてマスクを生成します。手順は至ってシンプルです。まず最初に、 ChromaColor を同じ ExtractColor 関数で実行します (使用している場合はノーマライズなど)。次に、カラーマップと ChromaColor の差を出します。そして、 長さの差を計算し、特別に指定したエラー範囲を切り離すために鮮明なマスクが幅広いグラディエントから抽出されます。
上の ExtractColor 関数をノードで表した例がこちらです。
この例では 'Chroma Alpha Strength' をマルチプライヤーとして使用していることに注目してください。エッジのシャープさを直観的に指定できる方法です。UE4 でパッケージ化されたマテリアル関数の中で、Min と Max を使って指定します。結果は同じですが、常に Max が Min より高くなるように設定する必要があり、Min は常に調整する必要があります。
デスピル
クロマキーを使ってアルファ マスクを抽出したら、残りのピクセルをデスピル します。これは重要なステップです。被写体のシルエット上のに被っている緑色のキャストをすべて取り除くという意味です。ライティングとカメラの両方にさまざまなエフェクトが付いているため必要になります。ひとつには、グリーン スクリーンが大きくなるほど、被写体上にキャストされる緑色のバウンスライトは増えます。また、バウンスライトをセット上で最小限にしたとしても、カメラはさまざまなレンズ アーティファクトを拾いやすいので、被写体上の明るいピクセルから若干ブルームが生じる可能性があります。
デスピル処理には、まずアルファ マスクと設定を同じにしてみます。ただし、マスクをソフトにするために値の幅は広くします。ビルトインされた関数の中で、別の Despill Max を公開します。デスピル処理に使う Min はアルファの Min と同じ値を使用します。
デスピル アルファができたら、それを使って画像からクロマ カラーのキャストを取り除きます。最初はデスピル アルファを使って単にデサチュレートだけしていましたが、クロマ カラーに一致する色の一部をソース画像から差し引いた方がうまく行くことがわかりました。
Despill Alpha を使って画像からクロマのカラースピルを除去するために使用することができます。
この画像の場合、2 つの Chroma Colors ノードと 2 つの Chroma Key Alpha ノードを使えば、さらに品質を高めることができます。カラーマップでは床 と壁の色がかなり違うことが分かります。従って、クロマ比較が単一の場合、限界値の範囲をもっと広げる必要があります。つまり、エッジの柔らかさの柔軟性が失われてしまい、その結果、モーション ブラーがかかったレバーなどの部分を修正するのが大変になります。2 つのクロマで比較する場合、それぞれのアルファの結果は Min によって 1 つにまとめられます。Despill Alphas は Max を使って 1 つにまとめることができます。
疑似的なバウンスの追加方法はとてもシンプルです。基本の画像カラーを使用する前に、手書きのコードで指定したバウンスまたはバックグラウンの色でデサチュレートするのは良いアイデアです。その理由は 2 つあります。1 つ目は、元の画像に存在するキャストをすべて除去して、ルミナンスだけを必要とする状態にすること。2 つ目は、ほとんどのキャストは 視射角のためスペキュラ サーフェスからとなり、メタル以外のすべてのマテリアルの場合、スペキュラは完全にデサチュレートされ、ライティングのみで色が付くこと。
専門的に合成を行う人は、別にレンダリングしたエレメントを使って正しいライティング反応を選択しやすくするなど、疑似的なライティングのマスクおよび追加方法についてかなり詳しくなければなりません。この部分は本記事の趣旨から少し外れていますが、少なくともライブ合成のアプローチがどんなものか分かってもらえると嬉しいです。
もう 1 つ、エピックの映像制作チームの Joe Wilson が提供してくれた品質の良い画像を使った例を紹介しましょう。これは、Tools Programmer の Lauren Ridge を WWDC (ページ冒頭にリンクがあります) で発表された Star Wars VR Experience デモの制作中に撮影したショットです。オリジナル画像の品質が高いと、それだけ結果も良くなります。この例では、クロマキー アルファの現行バージョンを使っています。
最後のフレームに追加したバウンスは、エッジの周り以外の、Vive ヘッドセットとコントローラーなど特に暗めに反射する部分の上では分かりにくい場合があります。追加したバウンスはこれらのエレメント上に空の反射を取り込み、合成画像にフィットしやすくします。
デスピルおよびバウンス/エッジ調整カラーを追加すると、上記の設定に必要なすべてのマテリアルはこのようになります。
Composure
冒頭で Composure について軽く触れました。まだクロマキー モードを Composure に追加していませんが、いろんな例を見てみたところ、とても簡単に設定できそうな感じでした。さまざまな合成設定に対応する Final Compositing Material というものがあります。サンプル プロジェクトの場合、カラーマスクはすべて Nuke などのプログラムからインポートされますが、マテリアルでの使用はここで説明したクロマキー ノードを使った置き換えと同じくらい簡単のはずです。
説明は以上です。 複合現実とアンリアル エンジンを使って、アンリアル コミュニティのみなさんがどんな作品を作ってくれるのか、楽しみにしています。
--
編集者注: 本ブログは Ryan の個人ブログ ShaderBits.comに掲載されたオリジナルをアンリアル エンジン コミュニティに幅広く伝えるために再編集しました。@ShaderBitsで Ryan をフォローしましょう。