Unreal Engine 5でカラーシャドウ半影を実装する

ハイエンドのリアルタイムレンダリングにおいて、光と影の遷移部—すなわち半影—はしばしば単純な線形グラデーションで表現されます。多くのシナリオで物理的に妥当であるものの、時にそれが無機質に感じられ、スタイライズされたシネマトグラフィや特定の自然現象に見られる芸術的な「インパクト」に欠けることがあります。「カラーシャドウ半影」(またはカラーシャドウターミネータ)エフェクトは、遷移領域に彩度を加えることで、光が影に接するエッジをより鮮やかで視覚的に興味深いものにします。

この手法は、Romain Durand の研究に触発され、Shahriar Shahrabi によって理論的に文書化されたもので、半影内の表面色を操作し、より飽和したグローや光のにじみをシミュレートすることに焦点を当てています。

UE5での技術的実装

これをポストプロセスエフェクトとして実装する代わりに(ポストプロセスは光/影の値を推測する必要があり、Lumen や昼夜サイクルといった動的システムで問題になることがあります)、このアプローチはエンジンシェーダーを直接編集します。これにより、すべての光タイプでエフェクトが機能し、計算コストも低く抑えられます。

Substrate 用実装

Substrate フレームワークを使用しているユーザーは、Engine\Shaders\Private\Substrate\SubstrateDeferredLighting.ush を修正します。

UE 5.7 の約 190 行目にある次の行を探します:

float3 SpecularLuminance = BSDFEvaluate.IntegratedSpecularValue * LightData.SpecularScale;

この直後に、以下のコードブロックを挿入します:

// Colored shadow penumbra - Start
const float PenumbraSaturation = 4.0f; // Configure this to your liking (1.0 means no change)

float3 LuminanceFactors = float3(0.3f, 0.59f, 0.11f); // Luminance factor for desaturation
float3 PenumbraColor = dot(DiffuseLuminance, LuminanceFactors); // Desaturate
PenumbraColor = lerp(PenumbraColor, DiffuseLuminance, PenumbraSaturation); // Apply saturation
DiffuseLuminance = lerp(DiffuseLuminance, PenumbraColor, 1.0f - BSDFShadowTerms.SurfaceShadow); // Blend
// Colored shadow penumbra - End

標準デファードライティング用実装

Substrate を使用していない場合は、Engine\Shaders\Private\DeferredLightPixelShaders.usf を編集します。

UE 5.7 の約 397 行目にある次の行を探します:

OutColor += Radiance;

その直後に、以下のスニペットを挿入します:

// Colored shadow penumbra - Start
const float PenumbraSaturation = 4.0f; // configure this to your liking (1.0 means no change)

float3 LuminanceFactors = float3(0.3f, 0.59f, 0.11f); // Luminance factor for desaturation
float3 PenumbraColor = dot(OutColor.xyz, LuminanceFactors); // Desaturate
PenumbraColor = lerp(PenumbraColor, OutColor.xyz, PenumbraSaturation); // Apply saturation
OutColor.xyz = lerp(OutColor.xyz, PenumbraColor, 1.0f - SurfaceShadow); // Blend
// Colored shadow penumbra - End

ファイルを保存したら、Ctrl + Shift + . を使用して Unreal Engine のシェーダーコンパイルを再起動します。

分析とトレードオフ

この実装は、開発者が考慮すべきいくつかの利点と欠点を提供します:

長所

  • 一貫性: すべての光タイプで動作し、ポストプロセスソリューションに伴う「推測ゲーム」を回避します。
  • パフォーマンス: 実装は非常に軽量で、ピクセルシェーダーへのオーバーヘッドはほぼ無視できる程度です。
  • 互換性: エンジンのソースコードを変更せずに、Launcher バージョンのエンジンでも使用できます。

短所

  • グローバル設定: 彩度は全体で一括設定され、光ごとやシーンごとに調整できません。
  • ソフトシャドウが必要: 効果は広い半影が存在する場合にのみ見えます。
  • 動的光のみ: この実装は動的光にのみ適用され、ベイクされたライティングには適用されません。
  • マテリアル依存: 効果は彩度を上げることに依存するため、グレースケールや既に完全に彩度が高い表面には目に見える影響がありません。

理論的背景と議論

実装は実用的な「ハック」ですが、効果の物理的根拠はテクニカルアーティストの間で議論の対象となっています。ある人は、特定のマテリアルが強い照明下で「光る」様子を模倣していると指摘し、照らされた部分から影の部分へにじむ光が、反射光自体よりも彩度が高いと考えています。

この手法の議論でコミュニティメンバーが指摘したように:

強く照らされたものは「光る」ことがあり、その光は反射光よりも色彩が豊かです。そのため、照明がハードエッジの場合、半影はより強く照らされた部分の光によって彩度が上がることがあります。

このことは、効果が厳密な物理シミュレーションというよりはスタイリスティックな選択である可能性があるものの、PenumbraSaturation の値を慎重に調整して過度に人工的な外観にならないようにすれば、影の遷移に視覚的な深みと「ブルーム」を加える強力なツールとなります。

Sources