マニフェスト仕様 (pack.json)

pack.json フォーマット 1 の仕様、多言語対応、材質分類ルール(classes)、パラメータ定義(params)について解説します。

マニフェスト概要

pack.json は、シェーダーパックの識別情報、多言語の説明文、対応モデルの推奨事項、材質分類ルール、調整用パラメータを宣言する JSON 形式の設定ファイルです。MMDX12 はパックの読み込み時にまずこのファイルを検証します。

{
  "format": 1,
  "id": "my_pack",
  "version": "1.0.0",
  "apiVersion": 1,
  "minAppVersion": "1.2.0",
  "name": { "ko": "내 팩", "en": "My Pack", "ja": "マイパック", "zh": "我的着色器" },
  "description": { "ko": "원신 풍 툰 셰이딩입니다.", "en": "Cel shading for anime models." },
  "recommendedFor": { "ko": "Genshin, Star Rail 공식 모델", "en": "Official HoYoverse MMD models" },
  "authors": [ { "name": "YourName", "role": "Shader", "url": "https://github.com/..." } ],
  "license": "MIT",
  "homepage": "https://...",
  "repository": "https://github.com/...",
  "tags": ["toon", "anime"],
  "classes": [
    { "class": "eye",  "match": ["目", "眼", "瞳", "eye", "Eye"] },
    { "class": "face", "match": ["顔", "颜", "face", "Face", "表情"] },
    { "class": "hair", "match": ["髪", "髮", "hair", "Hair"] },
    { "class": "skin", "match": ["肌", "皮膚", "skin", "Skin"] }
  ],
  "params": [
    { "key": "softness", "label": { "ja": "やわらかさ", "en": "Softness" }, "default": 0.1, "min": 0.0, "max": 1.0 }
  ]
}

各フィールドの仕様

必須項目

  • version (文字列): セマンティックバージョニング形式の文字列(例:"1.0.0")。更新通知やギャラリー配布で比較されます。
  • name (文字列または多言語オブジェクト): パックの表示名です。

識別情報と互換性

  • format (整数): マニフェストの仕様バージョンです。現在は 1 を指定します。
  • id (文字列): 半角英小文字 a-z、数字 0-9、アンダースコア _、ハイフン - で構成される最大 64 文字。省略時はフォルダ名が使用されます。インストール済みパックの場合、フォルダ名と一致している必要があります。
  • apiVersion (整数、既定値 1): 対象とするシェーダー API のバージョンです。実行中のアプリがサポートするバージョン(現在は 2)より大きい場合は「非互換」となり読み込まれません。
  • minAppVersion (文字列、任意): 動作に必要な最小 MMDX12 バージョン(例:"1.2.0")。

メタデータと多言語対応

  • 多言語フィールド: name、description、recommendedFor、パラメータの label は単一の文字列、または ko、en、ja、zh キーを持つオブジェクトで記述できます。
    • 表示言語の優先順位: アプリの表示言語 -> en -> 単一文字列 -> ko -> その他定義済みの言語。
  • authors (配列): 作者情報のリスト。各項目には name(必須)、role(任意、担当役割)、url(任意、http:// または https:// のリンク)を指定します。下位互換性のため旧形式の "author": "名前" も解釈されます。
  • license (文字列): SPDX 等のライセンス表記(例:"MIT", "CC-BY-4.0")。
  • homepage, repository (文字列): 公式サイトやソースコードのリポジトリ URL(http:// または https:// のみ)。
  • tags (文字列配列): 検索用タグのリスト(半角小文字、最大12個)。

材質分類ルール (classes)

MMD の PMX モデルは材質の命名規則が作者ごとに異なります。classes を定義することで、モデルの材質を以下の 6 つの標準クラスへ自動で分類できます:

  1. body (既定値:どのルールにも一致しない材質)
  2. skin (肌)
  3. face (顔)
  4. eye (瞳・目)
  5. hair (髪の毛)
  6. weapon (武器・小物)

判定の流れ

  • ルール配列は上から下へ順番に評価されます。
  • 最初に一致したルールが適用されます。
  • match 配列に含まれる各文字列が、PMX 材質の日本語名または英語名に部分一致するかどうかを検査します。
"classes": [
  { "class": "eye",  "match": ["目", "眼", "瞳", "eye", "Eye"] },
  { "class": "face", "match": ["顔", "颜", "face", "Face", "表情"] },
  { "class": "hair", "match": ["髪", "hair"] },
  { "class": "skin", "match": ["肌", "skin"] }
]

HLSL 側では s.materialClass に PACK_BODY、PACK_SKIN、PACK_FACE、PACK_EYE、PACK_HAIR、PACK_WEAPON が渡され、条件分岐が可能になります。

パラメータ設定 (params)

ユーザーが UI 上のスライダーでリアルタイムに調整できる浮動小数点値です:

  • 最大数: 最大 16 個まで(PackParam(0) から PackParam(15))。
  • 順序: JSON 配列の並び順がそのまま HLSL 内の引数インデックスとなります。
  • 属性:
    • key (文字列): モデルごとの設定保存に使用される一意の識別子です。将来のバージョン更新時もこのキーを変更しないことでユーザーの設定が保護されます。
    • label (文字列または多言語オブジェクト): UI に表示されるスライダー名。
    • default (数値): 初期値。
    • min, max (数値): スライダーの最小値と最大値。
  • 設定保存の挙動: 初期値から変更された項目のみがモデル設定に保存されます。変更されていない項目は、パック作者が新しい初期値を配布した際に自動的に新設定が反映されます。

パックテクスチャ (textures、API 2)

モデル自身のテクスチャだけでは作れないルックがあります。ゲーム風のトゥーンシェーディングにはライトマップ、クール/ウォームランプ、 顔の SDF、マットキャップ、パラメーター LUT などの追加テクスチャが必要です。パックはそれらを pack.json で宣言し、 PackSampleTex でサンプリングします(シェーダー API を参照)。テクスチャを使うパックは "apiVersion": 2 にします。

"apiVersion": 2,
"textures": [
  { "file": "textures/body_lightmap.png", "address": "clamp", "srgb": false },
  { "file": "textures/body_ramp.png",     "address": "clamp", "srgb": true }
]
  • file: パックフォルダーからの相対パス。png、jpg、jpeg のみ。.. や絶対パスは使えません。
  • address: "wrap"(既定)または "clamp"。ランプは必ず clamp にしてください。明るい側の端が u = 1.0 にあるため、wrap ではそこで影側の端がサンプリングされます。
  • srgb(既定 true): カラーテクスチャ。リニア値で返るので SrgbToLinear を重ねて適用しないでください。ライトマップ・SDF・LUT などのデータマップは false にすると保存値のまま返ります。
  • 上限: 最大 16 枚、1 枚あたり 4096 × 4096 以下、パック全体で 32 MB 以下。
  • 配列の順番が HLSL のインデックスです(PackSampleTex(0, uv) が最初の項目)。

ユーザーテクスチャフォルダー

ゲームから抽出したテクスチャは各社の著作物であり、再配布できません。そのためパックは pack.json と surface.hlsl だけを配布し、 テクスチャはユーザーに用意してもらう形にできます。シェーダー管理画面では、テクスチャを宣言したパックごとにテクスチャフォルダーを 指定できます。テクスチャは次の順番で探されます。

  1. ユーザーのテクスチャフォルダー:同じ相対パス(textures/body_ramp.png)、なければ同じファイル名(body_ramp.png)
  2. パックフォルダー
  3. 白の 1 × 1 代替テクスチャ。パックはそのままコンパイル・描画され、管理画面に不足しているテクスチャの数が表示されます。

ギャラリーに公開するパックには、再配布が許可されたテクスチャだけを含めてください。

キャラクターごとのフォルダーとファイル名の末尾一致

ゲームのテクスチャはキャラクターごとに異なるため、テクスチャフォルダーはキャラクターごとにも指定できます(ライブラリパネル、 再生バー、スタジオのインスペクターで、パックのスライダーの下にある「テクスチャフォルダー」の行)。パック単位のフォルダーより優先されます。 ユーザーフォルダーでは同じ相対パス、同じファイル名の順に探し、それでもなければ名前が _ + 宣言した名前で終わるファイルを探します (大文字小文字は区別せず、最も短い名前が優先)。共通の末尾だけを宣言すれば、元のファイル名のまま使えます: Body_Lightmap.png は Avatar_Girl_Pole_Hutao_Tex_Body_Lightmap.png を見つけます。

テクスチャによる分類

classes のルールは "texture" で材質のディフューズテクスチャのパスにも一致させられます。ゲームのマップは材質名ではなく テクスチャシートに従うため(髪のシートに描かれた帽子には髪のライトマップが必要)、こちらが確実です。

{ "class": "hair", "texture": ["发", "髮", "髪", "hair"] }

match の文字列が材質名にある、または texture の文字列がテクスチャのパスにあればルールが一致し、最初に一致したルールが使われます。