画面エフェクトパック
画面全体にかかるポストプロセスパック (API 3): 色収差、フィルムグレイン、CRTなど。マニフェスト項目、PackEffect、ステージ、エフェクトスタック、オンラインギャラリー。
エフェクトパックとは
サーフェスパックは1体のキャラクターのマテリアルのシェーディングを置き換えます。エフェクトパック ("type": "effect") は代わりに完成したフレーム全体に働きます。色収差、フィルムグレイン、CRT走査線、グリッチ、独自のビネットなどです。エフェクトはモデルではなく画面全体に属します。
エフェクトはアプリに同梱されていません。シェーダータブのオンライン一覧 (ギャラリー) からインストールするか、zipを取り込んでください。現在ギャラリーには chromatic_aberration、film_grain、crt_scanlines があります。エフェクトパックには MMDX12 1.4.0 以降 (APIバージョン3) が必要です。
エフェクトを使う
- シェーダータブのオンライン一覧からエフェクトパックをインストールします。
- ロビーのシェーダータブで画面エフェクトの行を開くか、再生バーのキラキラボタンを押します。
- 使うエフェクトをオンにし、矢印で順番を変え、スライダーを調整します。
スタックは最終画像に上から下へ実行されます。再生画面、ロビーのプレビュー、リアルタイムの動画・静止画レンダー (ラスター、リアルタイムRT、リアルタイムPT) に適用されます。オフラインGIレンダラー、アンリット・ワイヤーフレーム表示、スタジオの4分割ビューには適用されません。有効なエフェクトがなければ追加のターゲットもパスもなく、この機能のないビルドと同一のフレームになります。
コマンドラインでは --effect <id>[,<id>...] でその実行のスタックを置き換え、--effect none で空にします。
フォルダー構成
my_effect/
pack.json マニフェスト (サーフェスパックと同じ項目 + type / stage)
effect.hlsl PackEffect を実装
preview.png 任意、16:9 推奨
textures/ 任意、pack.json の "textures" (サーフェスパックと同じ規則)
マニフェストの追加項目
{
"format": 1,
"id": "film_grain",
"version": "1.0.0",
"apiVersion": 3,
"minAppVersion": "1.4.0",
"type": "effect",
"stage": "post",
"name": { "ja": "フィルムグレイン", "en": "Film grain" },
"params": [
{ "key": "strength", "label": { "ja": "強さ", "en": "Strength" }, "default": 0.12, "min": 0.0, "max": 0.6 }
]
}
"type": "effect"でエフェクトパックになります (既定は"surface")。"stage"は"post"(既定) または"pre-bloom"です。classesは使いません。params(最大16個) とtextures(最大16個) はサーフェスパックと全く同じに動きます。マニフェストを参照してください。
| stage | 入力と出力 | 用途 |
|---|---|---|
post | トーンマップとカラーLUTの後の表示用sRGB、8ビット | グレイン、走査線、レンズのにじみ、ビネット |
pre-bloom | ブルームの前のリニアHDR RGBA16F | グロー向き、露出を考慮するエフェクト |
両方のステージのエフェクトを1つのスタックに混在できます。各ステージは自分のエフェクトだけをスタック順に実行します。
effect.hlsl
パックは関数を1つ実装します。
float3 PackEffect(PackEffectInput i) { return i.color.rgb; }
PackEffectInput のフィールド:
| フィールド | 意味 |
|---|---|
uv | テクセル中心、0..1、左上 = (0, 0) |
pixel | SV_Position.xy (ピクセル) |
outputSize | 出力解像度 (ピクセル) |
time | シーン開始からの秒数 |
frameIndex | フレームカウンター (64で循環) |
color | このピクセルのここまでの画面 (アルファ保持) |
depth | 生のデバイス深度、1 = 背景 (LinearZ() で変換) |
normal | ワールド空間の法線、背景では未定義 |
motion | モーションベクトル、uv(現在) - uv(前) |
ヘルパー:
gEffectSource.SampleLevel(gLinear, uv, 0)はここまでの画面の任意のピクセルを読みます (バイリニア、クランプ)。レンズ系エフェクトが周囲を見る方法です。PackParam(i)はpack.jsonの順で i 番目のパラメーターのスライダー値 (または既定値) です。PackFxSampleTex(i, uv)、PackFxSampleTexLevel、PackFxTexSize、PackFxTexCountでパックのテクスチャをサンプリングします。sRGBテクスチャはリニア値を返します。common.hlsliのすべて:Luminance、LinearZ、Ign、SrgbToLinear、gTimeなど。
line はHLSLの予約語です。
例: 色収差
float3 PackEffect(PackEffectInput i) {
const float2 dir = i.uv - 0.5;
const float r = length(dir) * 1.41421356; // 中心0、隅1
const float2 offset = dir * (PackParam(0) * 0.03 * pow(r, PackParam(1)));
float3 c;
c.r = gEffectSource.SampleLevel(gLinear, i.uv + offset, 0).r;
c.g = i.color.g;
c.b = gEffectSource.SampleLevel(gLinear, i.uv - offset, 0).b;
return c;
}
赤と青を画面中心から離れる向きにサンプリングし、端ほどずれが大きくなります。
コンパイルとデバッグ
シェーダーは実行時にDXC (ps_6_0) でコンパイルされます。コンパイルエラーではそのエフェクトをスキップし、mmdx12.log に [E] 行を書き、トーストとシェーダーマネージャーの状態で知らせます。クラッシュはしません。アプリの実行中に effect.hlsl を保存すると再読み込みされます。
コマンドラインでは pack_check <フォルダー|zip> --compile で検査します。デバッグを参照してください。出発点には配布物の shaders/pack_template_effect を使えます。
公開
エフェクトパックもサーフェスパックと同じzip構成、バージョン、審査規則に従います。公開を参照してください。APIバージョンが3なので "minAppVersion": "1.4.0" を指定してください。