매니페스트 (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": { "ko": "경계 부드러움", "en": "Softness" }, "default": 0.1, "min": 0.0, "max": 1.0 }
]
}
필드 명세
필수 필드
version(문자열): 팩의 시맨틱 버전 (예:"1.0.0"). 업데이트 감지와 갤러리 배포에 사용됩니다.name(문자열 또는 다국어 객체): 팩의 표시 이름입니다.
식별자 및 호환성
format(정수): 매니페스트 형식 버전입니다. 현재 버전은1입니다.id(문자열): 영문 소문자a-z, 숫자0-9, 밑줄_, 하이픈-만 포함할 수 있으며 최대 64자입니다. 생략 시 폴더 이름이 자동으로 ID가 됩니다. 설치된 팩의 폴더 이름과id가 불일치하면 오류로 처리됩니다.apiVersion(정수, 기본값1): 대상pack_api.hlsli버전입니다. 실행 중인 앱의 지원 버전(현재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가지 표준 분류 중 하나로 자동 매핑합니다:
body(기본값: 어떤 규칙에도 맞지 않는 모든 재질)skin(피부)face(얼굴)eye(눈동자)hair(머리카락)weapon(무기·소품)
매칭 방식
- 규칙 배열은 위에서 아래 순서대로 평가되며, 가장 먼저 일치한 규칙이 적용됩니다.
match배열의 각 문자열이 PMX 재질의 일본어 이름 또는 영어 이름에 부분 문자열(Substring)로 포함되어 있는지 확인합니다.
"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 슬라이더로 조절할 수 있는 부동소수점(float) 파라미터입니다:
- 최대 개수: 최대 16개 (
PackParam(0)부터PackParam(15)까지). - 정렬 순서: 매니페스트에 나열된 순서가 곧 HLSL의 인덱스 번호가 됩니다.
- 속성:
key(문자열): 모델 설정 저장 시 사용되는 고유 키값입니다. 새 버전을 배포할 때도 키를 유지해야 사용자의 기존 설정이 보존됩니다.label(문자열 또는 다국어 객체): UI에 표시될 이름입니다.default(실수): 기본값.min,max(실수): 슬라이더의 최소 및 최대 범위.
- 설정 저장 원리: 사용자가 기본값에서 한 번이라도 조절한 항목만 키(
key)별로 모델 프로필에 저장됩니다. 손대지 않은 파라미터는 팩 제작자가 기본값을 바꿨을 때 자동으로 새 기본값을 따릅니다.
팩 텍스처 (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장, 장당 4096 × 4096 이하, 팩 전체 32 MB 이하.
- 배열 순서가 HLSL의 인덱스입니다 (
PackSampleTex(0, uv)가 첫 번째 항목).
사용자 텍스처 폴더
게임에서 추출한 텍스처는 제작사의 저작물이라 재배포하면 안 됩니다. 그래서 팩은 pack.json과 surface.hlsl만 배포하고
텍스처는 사용자가 직접 준비하게 할 수 있습니다. 셰이더 관리 화면에서 텍스처를 선언한 팩마다 텍스처 폴더를 지정할 수 있으며,
텍스처는 다음 순서로 찾습니다.
- 사용자 텍스처 폴더: 같은 상대 경로(
textures/body_ramp.png), 없으면 같은 파일 이름(body_ramp.png) - 팩 폴더
- 흰색 1 × 1 대체 텍스처. 팩은 그대로 컴파일·렌더링되고, 관리 화면에 빠진 텍스처 수가 표시됩니다.
갤러리에 올리는 팩에는 재배포 권리가 있는 텍스처만 넣어야 합니다.
캐릭터별 폴더와 파일 이름 끝 맞추기
게임 텍스처는 캐릭터마다 다르기 때문에 텍스처 폴더를 캐릭터별로도 지정할 수 있습니다 (라이브러리 패널, 재생 바, 스튜디오
인스펙터에서 팩 슬라이더 아래의 “텍스처 폴더” 줄). 캐릭터별 폴더가 팩 단위 폴더보다 우선합니다.
사용자 폴더에서는 같은 상대 경로, 같은 파일 이름 순으로 찾고, 그래도 없으면 이름이 _ + 선언한 이름으로 끝나는 파일을
찾습니다 (대소문자 무시, 가장 짧은 이름 우선). 공통 끝부분만 선언하면 원래 파일 이름을 그대로 쓸 수 있습니다:
Body_Lightmap.png는 Avatar_Girl_Pole_Hutao_Tex_Body_Lightmap.png를 찾습니다.
텍스처로 분류하기
classes 규칙은 "texture"로 재질의 디퓨즈 텍스처 경로를 매칭할 수도 있습니다. 게임 맵은 재질 이름이 아니라 텍스처 시트를
따르므로(머리카락 시트에 그려진 모자는 머리카락 라이트맵이 필요) 이 방식이 정확합니다.
{ "class": "hair", "texture": ["发", "髮", "髪", "hair"] }
match 문자열이 재질 이름에 있거나 또는 texture 문자열이 텍스처 경로에 있으면 규칙이 맞으며, 여전히 첫 번째로 맞는 규칙이 이깁니다.