
物理的に正確なレンダリングのおかげで、Unreal Engine 4は現実的なゲームの開発を容易にします。 レンダリングモデルは、光とマテリアルの相互作用をシミュレートし、リアルな画像を作成します。 ただし、様式化された外観のゲームを開発する場合は、他の手法を検討する必要があります。
スタイリングを作成する1つの方法は、 セルシェーディング (トゥーンシェーディングとも呼ばれます)を使用することです。 この手法は、漫画やアニメで一般的に使用されるシェーディングを模倣しています。 その使用例は、 Jet Set Radio 、 The Legend of Zelda:The Wind Waker 、 Gravity Rushなどのゲームで見ることができます。
このチュートリアルでは、次のことを学びます。
- 後処理素材を作成して使用する
- セルシェーダーを作成する
- 個々のメッシュのセルシェーダーを分離する
- ルックアップテーブルを使用してカラーバーを管理する
注:このチュートリアルでは、Unreal Engineの基本をすでに理解していることを前提としています。 Unreal Engineを初めて使用する場合は、まず初心者向けのUnreal Engineの 10部からなるチュートリアルを学習する必要があります。
仕事を始める
空白のプロジェクトをダウンロードして解凍します。 プロジェクトフォルダーに移動し、 CelShader.uprojectを開きます 。 次のシーンが表示されます。

これは、セルシェーディングを適用するキャラクターです。 始める前に、セルシェーディングとは何かを理解する必要があります。
セルシェーディングとは何ですか?
セルシェーディングは、連続的なグラデーションではなく、複数の色の縞を使用したレンダリングプロセスです。

以下は、 ゼルダの伝説ブレスオブザワイルドのセルシェーディングの使用例です。 セルシェーディングはキャラクターにのみ実装され、背景は通常のままであることに注意してください。

この画像には3つのストライプがあります。1つはシャドウ、1つは中間色、もう1つはハイライト用です。
オブジェクトに輪郭がある場合、セルシェーディングが適用されると誤解されることがよくあります 。 この例はBorderlandsです。 このゲームの外観は定型化されていますが 、実際にはセルシェーディングはありません 。 これは下の画像で見ることができます。 文字の色付けにはカラーストライプは使用されないことに注意してください。

アウトラインはセルシェーディングではありませんが、しばしば一緒に使用されます。 これにより、絵はインクやインクで塗られたようになります。 この手法は、 Guilty Gear XrdやDragon Ball FighterZなど、アニメスタイルのゲームでよく使用されます。

次のセクションでは、セルシェーディングを実装する方法を学習します。
実装方法セルシェーディング
最も一般的な実装方法は、表面の方向(「法線」と呼ばれる)と光の方向を比較することです。 法線とライトの方向の間のスカラー積を計算することにより、-1から1の値を取得します。
-1の値は、サーフェスとライトの方向が反対であることを意味します。 0は垂直であることを意味します。 1は同じ方向に向けられることを意味します。

スカラー製品のしきい値を設定することにより、複数のバンドを作成できます。 たとえば、スカラー積が-0.8より大きい場合、表面に暗い色を割り当てることができ、スカラー積が-0.8より小さい場合、色は明るいです。 そこで、2レーンのセルシェーダーを作成します。

この方法の制限は、他の光源がセルシェーディングでオブジェクトに影響を与えないことです。 さらに、オブジェクトは、セルシェーディングを使用してオブジェクトに影を落とすことはできません。
GIF

この問題を解決するには、別の方法を使用する必要があります。 スカラー積を計算する代わりに、表面の照度を計算します。 次に、しきい値を設定するときに、スカラー積の代わりにこの値を使用できます。
GIF

セルシェーダーとは何か、そしてどのように機能するかがわかったので、今度はセルシェーダーを作成します。
Celシェーダーの作成
このチュートリアルでは、セルシェーディングが後処理効果になります。 後処理(後処理)を使用すると、エンジンのレンダリングが完了した後に画像を変更できます。 後処理は、被写界深度、モーションブラー、ブルームなどの効果によく使用されます。
独自の後処理効果を作成するには、 後処理マテリアルを使用する必要があります。 Materialsフォルダーに移動して、新しいMaterialを作成します。 名前をPP_CelShaderに変更して開きます。
素材を後処理素材に変換するには、そのドメインを変更する必要があります 。 [詳細]パネルに移動し、[ 材料ドメイン]を[ ポストプロセス ]に変更します。

セルシェーダーを作成する最初のステップは、各ピクセルの照度を計算することです。 これを照明バッファーと呼びます。
照明バッファーの計算
Unrealが画面上に画像をレンダリングするとき、バッファへのパスを保存します。 ライティングバッファーを計算するには、次の2つのバッファーにアクセスする必要があります。
- ポストプロセス入力: Unrealがライティングとポストプロセスを完了した後、画像をこのバッファーに保存します。 さらに後処理を実行しない場合、プレーヤーに表示されるのは彼のUnrealです。
- 拡散色:これは、照明や後処理のないシーンです。 画面上のすべてのものの拡散色が含まれます。

これらのバッファにアクセスするには、 SceneTextureノードを使用する必要があります。 作成し、選択して[詳細]パネルに移動します。 ポストプロセス入力バッファにアクセスするには、 シーンテクスチャIDをPostProcessInput0に変更します 。

Diffuse Colorにアクセスするには、別のSceneTextureノードを作成します。 シーンテクスチャIDをDiffuseColorに変更します。

ライティングバッファには、グレースケール値のみを含める必要があります(ピクセルの照明の程度を記述)。 つまり、両方のバッファからの色情報は必要ありません。 色を破棄するには、両方のSceneTextureノードのColor出力をDesaturationに接続します。 これにより、両方のバッファが完全に変色します。

ライティングバッファーを計算するには、単にSceneTexture:PostProcessInput0をSceneTexture:DiffuseColorに分割します。 ここでは順序が重要です!

次に、 Clampを使用して、値が0〜1の範囲に留まるようにします。これにより、可能な値がわかるため、しきい値の作成が簡単になります。

ライティングバッファの視覚化を次に示します。

ご覧のとおり、照らされた領域は白に近く、照らされていない領域は黒に近くなります。
次に、ライティングバッファを使用してしきい値を作成します。
しきい値作成
セルシェーダーでは、0.5より大きい値を持つピクセルは通常の拡散色を使用します。 値が0.5未満のピクセルは、半輝度の拡散色を使用します。
最初に、 Ifノードを作成します。 これにより、2つの値を比較できます。 比較の結果に応じて、さまざまな出力を示すことができます。

次に、 クランプを入力Aに接続します。 次に、値が0.5の 定数を作成し、入力Bに接続します。

注:しきい値を変更するには、入力Bの値を変更できます。
色を取得するには、 SceneTextureを作成し、そのScene Texture IdをDiffuse Colorに設定します。 次に、 Colorに0.5を掛けて、半分の明るさの拡散色を取得します。

最後に、次のようにすべてを接続します。

要約すると:
- 彩度低下は、 ポストプロセス入力と拡散色をグレースケール画像に変換します
- Divideは、 ポストプロセス入力をDiffuse Colorに分割します。 そこで、ライティングバッファを作成します。
- クランプ制限値は0〜1です
- ライティング値が0.5より大きい場合、通常の拡散色を表示します。 0.5未満の場合、半分の明るさの拡散色が表示されます。
セルシェーダーができたので、それをシーンに適用する必要があります。
後処理材料の使用
後処理材料を使用するには、後処理ボリュームを作成する必要があります。 一般的に、ホワイトバランス、彩度、コントラストなどの後処理効果を制御するために使用されます。
[ 適用]をクリックして、メインエディターに戻ります。 ポストプロセスボリュームを作成するには、[モード]パネルに移動し、[ ボリューム]カテゴリを選択します。 次に、 ポストプロセスボリュームをビューポートにドラッグして作成します。
GIF

次に、セルシェーダーを使用するようにポストプロセスボリュームに指示する必要があります。 ポストプロセスボリュームを選択した後、詳細パネルに移動します。 次に、 Rendering Features \ Post Process Materialsを見つけて、 +アイコンをクリックします。 したがって、新しい要素を配列に追加します。

次に、[ 選択 ]ドロップダウンリストをクリックし、[ 資産参照]を選択します。

これにより、材料を選択できます。 [ なし]ドロップダウンリストをクリックして、[ PP_CelShader]を選択します。

デフォルトでは、Post Process Volumeは内部にいるときにのみ機能します。 しかし、私たちの場合、それが全世界に影響を与えることが必要です。 これを行うには、 「Post Process Volume Settings」までスクロールし、 Infinite Extent(Unbound)をオンにします。

セルシェーダーがゲーム全体に適用されたので、次のように表示されます。

「ちょっと待ってください、これは先ほど示したセルシェーダーとは違います!」
この違いの主な理由は、エンジンがトーン圧縮後にセルシェーダーを使用することです。 これを修正するには、トーン圧縮の前にセルシェーダーを使用するようエンジンに要求する必要があります。
トーンマッピング前のセルシェーディングの適用
プレーヤーに画像を表示する前に、Unrealは「トーンマッピング」として知られるプロセスを実行します。 トーン圧縮の目標の1つは、画像をより自然にすることです。 彼女は入力色を取り、曲線を使用して新しい値にシフトします。
トーンマッピングの前後の2つの画像を次に示します。

ご覧のとおり、階調圧縮前の明るい領域は明るすぎます。 ただし、トーン圧縮後、明るい領域は柔らかくなります。
階調圧縮は表示する必要のある画像には便利ですが、計算に使用する画像に対して階調圧縮を実行しないでください 。 値の偏りのため、予想される値は使用しません。
PP_CelShaderを開き、何も選択されていないことを確認します。 次に、パネルに移動して、 ポストプロセス材料セクションを見つけます。 Blendable LocationをBefore Tonemappingに設定します。

[ 適用]をクリックして、メインエディターに戻ります。 色がより良くなりました!

次のセクションでは、セルシェーディングを個々のオブジェクトにのみ適用する方法を学習します。
分離セルシェーダー
後処理の効果を分離するには、 Custom Depthと呼ばれる関数を使用する必要があります。 拡散色を使用した後処理入力と同様に、後処理マテリアルで使用できるバッファーでもあります。
カスタム深度とは何かを理解する前に、 シーン深度バッファを理解する必要があります。 シーン深度は、カメラからの各ピクセルの遠隔性を保存します。 シーン深度の視覚化は次のようになります。

カスタム深度は同じ情報を保存しますが、選択したメッシュについてのみです。 以下は、カスタム深度でレンダリングされたバイキングによる視覚化です。

シーン深度とカスタム深度を比較すると、オブジェクトを分離できます。 Scene DepthがCustom Depthよりも小さい場合、通常の画像を使用します。 Scene DepthがCustom Depthよりも大きい場合、セルシェーディング付きの画像が使用されます。
最初のステップは、カスタム深度でバイキングをレンダリングすることです。
カスタム深度の使用
World Outlinerに移動し、 SK_Vikingを選択します。 次に、[詳細]パネルに移動し、[ レンダリング]セクションを見つけます。 次に、 Render CustomDepth Passをオンにします。

次に、深さの比較を行う必要があります。 PP_CelShaderを開き、次の図を作成します。

注: マスク(R)ノードはコンポーネントマスクです。 これらを使用すると、マルチチャネルデータをスカラー値に変換できます。 入力AとBの Ifノードはスカラー値のみを取るため、シーン深度とカスタム深度をマスクする必要があります。
次に、セルシェーディングネットワーク出力をA> Bに接続します。 最後に、新しく作成したIfの出力をEmissive Colorに接続します。
セルシェーディングは、カスタム深度でレンダリングされたメッシュにのみ適用されるようになりました。
[ 適用]をクリックして、メインエディターに戻ります。 セルシェーディングがバイキングに対してのみ実行されることがわかります。

セルシェーダーはうまく機能しますが、非常に簡単です。 さらにバンドが必要な場合はどうなりますか? バンド間の遷移をよりスムーズにしたい場合はどうしますか? これはすべて、 ルックアップテーブル (LUT)を使用して実装できます。
「ルックアップテーブル」とは何ですか?
幼少期には、乗算とは何かを学びました。 しかし、若い脳は常にそのような計算を実行できるわけではありません。 したがって、計算の代わりに、乗算テーブルを使用して回答を「検索」できます。

実際、これはLUTです。 これは、入力データを使用してアクセスできる値の配列(通常は事前計算済み)です。 乗算表の場合、入力は乗数と乗数でした。
セルシェーダーのコンテキストでは、LUTは特定のグラデーションを持つテクスチャです。 LUTがどのように見えるかの例を4つ示します。

ここでは、拡散色に0.5を掛けて影の色を計算します。 0.5の定数を乗算する代わりに、LUTの値を使用します。 これにより、レーンの数とその遷移を制御できます。 LUTの外観によって、シェーディングがどのように見えるかを理解できます。
LUTを使用する前に、そのテクスチャパラメータの一部を変更する必要があります。
LUT設定の変更
Texturesフォルダーに移動し、 T_Lut_01を開きます 。 LUTは次のようになります。

変更する必要がある最初のパラメーターはsRGBです。 レンダリング時に、UnrealはsRGBが有効になっているすべてのテクスチャを線形カラーに変換します。 これにより、エンジンがレンダリング計算を実行しやすくなります。
sRGBパラメーターは、外観を記述するテクスチャに役立ちます。 ただし、法線マップやLUTなどのテクスチャには、数学計算用のデータが含まれています。 したがって、Unrealはそれらの値が真であると見なすべきです。 sRGBを無効にすると、Unreal はリニアカラーへの変換を実行しません 。
これを行うには、 sRGBの チェックを外します。 このパラメーターは、[ テクスチャ]セクションにあります。

変更する必要がある次のパラメーターは、テクスチャタイルメソッドです。 このテクスチャは表示されないため、タイルは必要ありません。 さらに、タイルを有効のままにすると、テクスチャのエッジでサンプリングするときに問題が発生します。 たとえば、左端からピクセルをサンプリングする場合、タイリングにより右端と混合しようとします。
タイリングを無効にするには、 X軸のタイリング方法の値をClampに変更します。 Y軸タイリング方法についても同じことを行います。

そして、パラメータの設定は完了です。 次に、後処理マテリアルでLUTを使用する必要があります。
LUTを使用する
T_Lut_01を閉じてPP_CelShaderを開きます 。 最初に強調表示されたノードを削除します。

次に、 テクスチャサンプルを作成し、そのテクスチャをT_Lut_01に変更します。 このLUTテーブルは、滑らかな遷移で3つのバンドを作成します。

思い出すように、LUTは入力を使用して出力する値を決定します。 この例では、ライティングバッファが入力として使用されます。
これを実装するには、 テクスチャサンプルでクランプとUVを組み合わせます。

これは、ライティングバッファとテクスチャ座標の値が0〜1であるため機能します。たとえば、ライティングバッファのピクセルが0.5の場合、LUTはテクスチャの中央からピクセル値を出力します。
次に、拡散色にLUTを掛ける必要があります。 これを行うには、次の図を再作成します。

Appendを使用して、 Texture Sampleの出力を4チャネルベクトルに変換します。 3チャネルベクトルに4チャネル( SceneTexture )を掛けることができないため、これが必要です。
最後に、すべてを次のように接続します。
ここで、拡散カラーに定数を掛ける代わりに、LUTからの値を掛けます。 そのため、カラーバンドの数とその遷移を(LUTに応じて)制御します。 出力LUT値は、ライティングバッファーによって決定されます。
[ 適用]をクリックし、 PP_CelShaderを閉じます 。 これで、シェーダーには3つのバンドがあり、バンド間の遷移がよりスムーズになります。

以下は、異なるLUTの外観の比較です。 これらのLUTもプロジェクトに追加されます。

次はどこに行きますか?
完成したプロジェクトはここからダウンロードできます 。
ご覧のとおり、後処理素材は非常に強力なツールです。 これらにより、多くの現実的で様式化された効果を作成できます。 後処理の詳細については、 後処理UEのドキュメントをご覧ください。