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リニアのテクスチャ色 × 素材色、ライティングなし
materialClassclasses ルールで決まる PACK_BODY / SKIN / FACE / EYE / HAIR / WEAPON
params[16]pack.json 順のスライダー値
headPos, headScale, headRight, headUp, headForward, headValidPackSurface と同じ頭ボーンのフレーム

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、パストレーサーの各バリアントをコンパイルします。