PT / GI パック
pt_surface.hlsl: パストレーサーとオフライン GI レンダラーでパックを適用する方法。PackEvaluate、PtPackIn / PtPackOut、テクスチャ、デノイザー、制限。
PT / GI パックとは
サーフェスパック(surface.hlsl)は PackShade でラスターとレイトレーシングのカメラビューをシェーディングします。パストレーサー(--render pt、PT 動画レンダラー)とオフライン GI レンダラー(GI の静止画・動画)はすべてのレイを 1 つのコンピュートシェーダー内で追跡するため、そこでは PackShade を実行できません。パックは2 つ目のファイル pt_surface.hlsl で参加できます。このファイルはヒット点の素材を記述します。太陽の影、間接光、放射照度キャッシュ、デノイザーといった光の輸送はレンダラーが担当し続けます。
MMDX12 1.5.0 以降が必要です。このファイルがないパックは PT と GI で標準シェーディングを使い、古いバージョンはこのファイルを無視します。
ファイル
my_pack/
pack.json マニフェスト(変更なし)
surface.hlsl ラスター / リアルタイム RT (PackShade)
pt_surface.hlsl パストレーサー / オフライン GI (PackEvaluate)
shared.hlsli 任意: 両方のファイルが使う計算
どちらのファイルもパックフォルダーの #include "shared.hlsli" を使えるので、見た目は一度書くだけで済みます。オンラインギャラリーのパック nimble_toon がこの構成です。
PackEvaluate
PtPackOut PackEvaluate(PtPackIn i);
PtPackIn
| フィールド | 意味 |
|---|---|
pos, normal, V, uv | ワールド位置、シェーディング法線、カメラ方向、テクスチャ座標 |
L, sunVis | 太陽方向、トレースした影レイによる太陽の可視性 0..1(拡散バウンスでは 0) |
baseColor | リニアのテクスチャ色 × 素材色、ライティングなし |
materialClass | classes ルールで決まる PACK_BODY / SKIN / FACE / EYE / HAIR / WEAPON |
params[16] | pack.json 順のスライダー値 |
headPos, headScale, headRight, headUp, headForward, headValid | PackSurface と同じ頭ボーンのフレーム |
PtPackOut(すべてのフィールドに代入してください。代入されないフィールドがあると pack_check が警告します)
| フィールド | 意味 |
|---|---|
albedo | リニアの表面色。拡散バウンスとデノイザーが見る値 |
shadowTint | 影側に掛けるリニアの係数 |
shadowBias | 境界を N.L 単位でずらす(平滑化した顔の法線: dot(Nsmooth, L) - dot(normal, L)) |
terminator | 境界 smoothstep の N.L 端点 (lo, hi)。(0, 0) ならエンジン既定 |
specular | 加算されるリニア放射輝度(リム、ツヤ、マットキャップ)。sunVis が掛かります |
flatFace | エンジンのフラット顔処理を使う(この表面に間接光のグラデーションなし) |
レンダラーの使い方
- カメラレイと鏡・ガラスのチェーン:
lerp(albedo * shadowTint, albedo, term * sunVis) * sunIntensity + specular * sunVis。ここでterm = smoothstep(lo, hi, N.L + shadowBias)。 - 拡散バウンス(他の表面が集める光):
albedoだけを使います。トゥーン項は収集レイでは実行されません。 - アンビエント項は足さないでください。パストレーサーが実際の間接光を追跡します。
- ハーフランバートのランプ
threshold ± softnessはterminator = (2 * (threshold - softness) - 1, 2 * (threshold + softness) - 1)に変換できます。
テクスチャ
pack.json で宣言したテクスチャを使えます(明示的 LOD のみ、暗黙の微分なし):
float4 PtPackSampleTex(uint i, float2 uv); // レベル 0
float4 PtPackSampleTexLevel(uint i, float2 uv, float lod);
uint PtPackTexCount();
float2 PtPackTexSize(uint i);
範囲外のインデックスやファイルがない場合は、PackSampleTex と同じく白になります。sRGB テクスチャはリニア値でサンプルされます。
制限
- キャラクターのみが対象です。ステージと小物にはパックは適用されません。
- 1 つのシーンに異なる PT パックが複数あると、最初のものを使います(警告がログに出ます)。
- オフライン GI レンダラーはアプリ標準の輪郭線を描きます(
PackEdgeはラスターと RT に適用)。 - デノイザーはパックの直接光を標準のトゥーン光と同じに扱います。静止画のテストでは硬い
step()のハイライト境界が鮮明に残りましたが、速い動きは確認していません。 PackEvaluateでは終了が定まらないループを避けてください。GPU がハングするとアプリが終了します。pack_check <フォルダー> --compileで確認してください。ラスター、オフライン GI、パストレーサーの各バリアントをコンパイルします。