
2026/05/08 4:04
着色されたシャドウペンシュア
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
本記事は、UE5 における Colored Penumbra(着色されたペヌンブラ/カラーシャドウターミネーター)効果を実装するための実用的な方法を詳細に説明しています。この方法はエンジンシェーダーを修正することで実現され、エンジンの全体を再コンパイルすることなく高品質な視覚表現を達成することを可能にします。この技術は元来、Romain Durand によって実証され、Shahriar Shahrabi にて理論的に説明されており、
SubstrateDeferredLighting.ush または DeferredLightPixelShaders.usf のいずれかを編集することで実現します。ユーザーはそれぞれ 190 行目以降または 397 行目以降に特定のブレンディングロジックブロックを挿入する必要があり、これには PenumbraSaturation(デフォルト値 4.0f)や標準的な輝度ファクターなどのパラメータを使用します。その後、Ctrl + Shift + .. を押して再コンパイルをトリガーします。このアプローチは費用対効果が高く、日周サイクルやダイナミックライトに関する trial-and-error を回避するものの、以下の制約があります:効果は ダイナミックライトのみで動作し(バインドライトでは機能しない)、光ごとの制御ではなくグローバルな飽和度を適用し、また広範囲のペヌンブラが存在しないと視認されない点です。さらに、この技術は表面の色饱和度を変更するため、グレーだけで構成されたシーンや完全に飽和した表面だけで構成されたシーンには可視効果が現れないため、万能なライティング修正ツールではなく、特定の美的意図向けの専用ツールとして位置付けられています。本文
2026 年 5 月 2 日 • 読み上げ時間:約 4 分
UE5
シェーダー
照明
数年前、ソーシャルメディア上に公開されたロマン・デュランによって実装されていた効果を目にしました。光源のシャドウ部分にあるペンシュマ(半影)領域に追加の色味が加わるもので、「Colored Penumbra(彩色半影)」または「Colored Shadow Terminator(彩色シャドウターミネーター)」と呼ばれています。私はこの効果を非常に気に入り、挑戦し、現在はこれを公開いたします。興味を持たれた方には、シェハリアル・シャハラビによる Medium 記事に理論的な解説が含まれているのでご参照ください。
実装方法はいくつかありますが、ここではエンジン固有のシェーダーを編集するアプローチを選定しました(もちろんすべての手法と同様に、利点と限界があります):
- ポストプロセスソリューションの場合のように「どの値が光源に対応し、どの値がシャドウに対応するか」を推測する必要がありません。これは特に Lumener や昼夜サイクルといったダイナミックな環境では苦痛を伴う可能性があります。
- すべての種類の光源と互換性があります。
- 実装は非常に軽量(コスト効率的)です。
- ただし、色飽和度の設定はシーン全体または全ての光源に対して一括で行う必要があり、個別の光源やシーンごとには調整できません。
- この効果が可視化されるためには、比較的一定した広さを持つペンシュマ領域が必要です。
- この実装はダイナミックな光源専用であり、ベイク(事前計算)された光源には適用されません。
今回はエンジン自体ではなく、エンジンのシェーダーのみを編集するため、ランチャー版でも問題なく動作します。シェーダーの編集に関する詳細については、以前の投稿でより詳しく解説していますので、その内容を事前に読んでおくことをお勧めします。
実装手順
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; // お好みの値に設定してください(1.0 は変更なし) float3 LuminanceFactors = float3(0.3f, 0.59f, 0.11f); // 非飽和化のための輝度係数 float3 PenumbraColor = dot(DiffuseLuminance, LuminanceFactors); // 非飽和化 PenumbraColor = lerp(PenumbraColor, DiffuseLuminance, PenumbraSaturation); // 再飽和化(非飽和の逆処理) DiffuseLuminance = lerp(DiffuseLuminance, PenumbraColor, 1.0f - BSDFShadowTerms.SurfaceShadow); // 融合処理 // Colored shadow penumbra - End
Substrate を使用していない場合は、以下のファイルをオープンしてください:
Engine\Shaders\Private\DeferredLightPixelShaders.usf
UE 5.7 の場合、397 行目付近で次のコードを見つけます(元のコード部分は抜粋されませんでしたが、文脈上追加位置は同様です):
// Colored shadow penumbra - Start const float PenumbraSaturation = 4.0f; // お好みの値に設定してください(1.0 は変更なし) float3 LuminanceFactors = float3(0.3f, 0.59f, 0.11f); // 非飽和化のための輝度係数 float3 PenumbraColor = dot(OutColor.xyz, LuminanceFactors); // 非飽和化 PenumbraColor = lerp(PenumbraColor, OutColor.xyz, PenumbraSaturation); // 再飽和化(非飽和の逆処理) OutColor.xyz = lerp(OutColor.xyz, PenumbraColor, 1.0f - SurfaceShadow); // 融合処理 // Colored shadow penumbra - End
シェーダーファイルを保存した後、Unreal エディタに戻り、
Ctrl + Shift + . キーを押ししてシェーダーの再コンパイルを開始してください。その間にコーヒーでも作っていただければ幸いです。
以上です。簡単でした :)
以下に、彩色半影効果の有無を比較したサンプル画像を示します(Quixel 由来の複数のシーンで検証済み):
[比較画像のプレースホルダー]
これらの比較画像では、表示目的のために効果が非常に強い設定となっていますが、実際には
PenumbraSaturation の値を低いほうに調整することをお勧めします。また、コードから分かる通り、この実装は表面の色をより飽和させるように変換するため、灰色または完全に飽和している表面上では効果が見られません。
ご質問やコメントなどございましたら、関連する Twitter ブースト、Bluesky 投稿、ArtStation、または LinkedIn の投稿へ返信していただくことを歓迎いたします。