fix(models): MMD 材质对齐——补回双面标志、规范化 PBR 参数、可选 unlit 着色
背景(用户反馈 + 本地用真 Assimp 6.0.4 复现): PMX 的着色模型(卡通阶梯 + 球面贴图 + 平坦环境光)与 glTF PBR 不是一回事, Assimp 转换会丢掉其中一部分。实测样本【奥黛塔】_by_原神.zip(39 个材质): 1. 主因:PMX 里 36 个材质带 drawFlag bit0(不剔除背面),而导出的 GLB 里 doubleSided 一个都没有 -> 头发/裙摆/睫毛这类薄片被单面剔除, 看起来就是颜色/贴图不对; 2. PMX 的 shininess/specular/ambient 与 PBR 无映射;Assimp 还会带上 KHR_materials_specular / KHR_materials_volume 等与 MMD 无关的扩展; 3. Assimp 把 accessor.min/max 写坏(实测 min = 2.2250738585072014e-308), Godot 等客户端用它算包围盒。 修复: 1. 新增 src/models/pmx-materials.ts:只读 PMX 材质段(布局与权威库 mmd-parser 一致,注意贴图索引宽度是 1 字节),拿到 name/diffuse/specular/shininess/ ambient/drawFlag/球面贴图/toon/faceCount; 2. 新增 src/models/glb-materials.ts:转换后按索引把 PMX 参数补回 GLB —— doubleSided、metallicFactor=0、roughnessFactor=clamp(1-shininess/100,0.5,1)、 baseColorFactor x diffuse(含 alpha);清掉与 MMD 无关的扩展; 修正全部浮点 accessor 的 min/max;支持 KHR_materials_unlit(MODEL_SHADING); 3. 抽出 src/common/glb-chunks.ts(JSON/BIN chunk 读写),vrm-writer 改为复用; 4. 能力边界写清楚:PMX 的球面贴图(该模型 15 项)与 toon 阶梯在 glTF core 里 没有对应槽位,任何转换器都无法保留,数量写进 conversion_note 供审核查看; 5. 新增 test/mmd-materials.spec.ts 9 项;规模 15 文件 / 220 项; 6. 新增 MODEL_SHADING 配置(默认 pbr,可选 unlit),文档同步(README.md/.txt、DSH.md、.env.example)。
This commit is contained in:
@@ -10,7 +10,18 @@ OpenDance Studio **阶段一**: Web 管理服务端(NestJS + TypeORM + 现有 My
|
||||
|
||||
## 状态
|
||||
|
||||
**阶段一已完成**: T-WEB-001 -> T-WEB-010 全部落地,当前版本 **v0.2.4**(契约 `rest-api / data-models / model-formats 0.4.0`、`database 0.3.0`)。
|
||||
**阶段一已完成**: T-WEB-001 -> T-WEB-010 全部落地,当前版本 **v0.2.5**(契约 `rest-api / data-models / model-formats 0.4.0`、`database 0.3.0`)。
|
||||
|
||||
v0.2.5 修订:
|
||||
|
||||
**MMD 材质/着色对齐**:PMX 的着色模型(卡通阶梯 + 球面贴图 + 平坦环境光)与 glTF PBR 不是一回事,Assimp 转换会丢东西。实测样本 `【奥黛塔】_by_原神.zip`(39 个材质):
|
||||
|
||||
1. **修复"看起来颜色/贴图不对"的主因**:PMX 里 **36 个材质带"不剔除背面"标志**,而 Assimp 导出的 GLB 里 `doubleSided` **一个都没有** -> 头发/裙摆/睫毛这类薄片被单面剔除。现在新增 `pmx-materials.ts`(只读 PMX 材质段)并在转换后按 `drawFlag` 补回 `doubleSided`;
|
||||
2. **PBR 参数规范化**(`glb-materials.ts`):`metallicFactor=0`、`roughnessFactor=clamp(1-shininess/100, 0.5, 1)`(MMD 常见 shininess=1 -> 0.99 哑光)、`baseColorFactor` 乘上 PMX diffuse(含 alpha);清掉 Assimp 带出的、与 MMD 无关的 `KHR_materials_specular` / `volume` / `transmission` / `ior` / `emissive_strength`;顺手修正 Assimp 写坏的 `accessor.min/max`(实测 min 被写成 `2.2e-308`,Godot 用它算包围盒);
|
||||
3. **新增 `MODEL_SHADING`**(默认 `pbr`,可选 `unlit`):`unlit` 会给每个材质写 `KHR_materials_unlit`,颜色 = 贴图 x baseColorFactor、与场景光照无关,最接近 MMD 的平涂观感(three.js 与 Godot 都支持);
|
||||
4. **说明(能力边界)**:PMX 的**球面贴图(该模型 15 项)与卡通 toon 阶梯在 glTF core 里没有对应槽位**,任何转换器都无法原样保留;服务端会把数量写进 `conversion_note`(审核面板可见),不会假装保留;
|
||||
5. 新增 9 项测试(`test/mmd-materials.spec.ts`);测试规模 15 文件 / 220 项;
|
||||
6. **注意**:材质修正在**转换时**生效,已有模型需重新导入(不是 `reanalyze-models.mjs`,它只刷新分析与缩略图)。
|
||||
|
||||
v0.2.4 修订:
|
||||
|
||||
@@ -66,15 +77,15 @@ v0.2.0 主要变更:
|
||||
3. 取得发布包并校验(地址用你们自己的制品库替换; 下面是本仓库的发布地址)
|
||||
|
||||
```bash
|
||||
curl -LO https://gitea.kasugano.cn/zijunchiang/opendance-web/releases/download/v0.2.4/opendance-web-v0.2.4.tar.gz
|
||||
curl -LO https://gitea.kasugano.cn/zijunchiang/opendance-web/releases/download/v0.2.4/SHA256SUMS
|
||||
curl -LO https://gitea.kasugano.cn/zijunchiang/opendance-web/releases/download/v0.2.5/opendance-web-v0.2.5.tar.gz
|
||||
curl -LO https://gitea.kasugano.cn/zijunchiang/opendance-web/releases/download/v0.2.5/SHA256SUMS
|
||||
sha256sum -c SHA256SUMS # 期望输出 "OK"
|
||||
```
|
||||
|
||||
4. 解压并生成配置(交互式引导,逐项问答,口令不回显)
|
||||
|
||||
```bash
|
||||
tar -xzf opendance-web-v0.2.4.tar.gz && cd opendance-web-v0.2.4
|
||||
tar -xzf opendance-web-v0.2.5.tar.gz && cd opendance-web-v0.2.5
|
||||
bash deploy/init-env.sh
|
||||
```
|
||||
|
||||
@@ -144,8 +155,8 @@ FLUSH PRIVILEGES;
|
||||
### 5. 部署步骤
|
||||
|
||||
```bash
|
||||
tar -xzf opendance-web-v0.2.4.tar.gz
|
||||
cd opendance-web-v0.2.4
|
||||
tar -xzf opendance-web-v0.2.5.tar.gz
|
||||
cd opendance-web-v0.2.5
|
||||
bash deploy/init-env.sh # 首次启动引导: 逐项问答生成 deploy/.env(见下)
|
||||
bash deploy/install.sh # 已以 root 登录, 不需要 sudo
|
||||
```
|
||||
@@ -286,6 +297,7 @@ bash /opt/opendance/deploy/ctl.sh status | restart | logs
|
||||
| 服务本机 curl 通、外部访问不了 | `bash deploy/check-access.sh` 一次定位:打印 `HOST`/`PORT`、实际监听地址、对外 IP 自测、80/443 有无反代、防火墙放行情况,并给出修复命令 |
|
||||
| 管理页面打开是 404 | 说明访问的是软件 API 端口(默认 3000);管理页面在管理端端口(默认 3001) |
|
||||
| 上传 `.zip` / `.pmx` / `.fbx` 报转换失败(ENOENT / Assimp 不可用) | PMX/FBX 转换依赖外部 Assimp:`apt-get install -y assimp-utils`(RHEL 系 `dnf install -y assimp`,`install.sh` 现在会尝试自动安装)。装好后**不需要重启服务**;若不在服务 PATH 中,在 `deploy/.env` 设 `ASSIMP_BIN` 为绝对路径。只上传 `.glb` / `.vrm` 则不需要它 |
|
||||
| 导入后的模型颜色/观感与 MMD 里不一致 | PMX 的着色(卡通阶梯、球面贴图、平坦环境光)在 glTF 里没有等价实现。v0.2.5 起会补回**双面**、规范化 PBR 参数并清掉无关扩展;想要最接近 MMD 的平涂颜色,把 `MODEL_SHADING=unlit` 写进 `deploy/.env` 后**重新导入**模型。球面贴图与 toon 阶梯无法保留,数量会记在模型的"转换说明"里 |
|
||||
| 列表/审核里的缩略图是"白模"(纯白模型) | v0.2.4 前的缩略图渲染器不采样贴图,而 MMD 模型的 `baseColorFactor` 是白色。升级到 v0.2.4 后重新生成缩略图:`cd /opt/opendance/web-server && node scripts/reanalyze-models.mjs --url http://127.0.0.1:3000 --force` |
|
||||
| 导入模型返回 **500 Internal server error** | 老库上多为 `models.stats` 超长(骨骼树按骨骼展开,643 骨骼即 70,980 字节 > TEXT 上限):执行 `ALTER TABLE models MODIFY stats MEDIUMTEXT NULL;` 或部署 v0.2.3(`install.sh` 会自动跑迁移)。v0.2.3 起服务端另有兜底,不会再 500 |
|
||||
| 安装时报 `command not found` / 退出码 127,且提示指向 `deploy/.env` 某一行 | 该行的值含空格或 shell 元字符却没加引号,被 shell 当成命令执行了。按预检提示给这个值加引号(如 `MODEL_CONVERT_PMX="Hatsune Miku.pmx"`)后重跑;`deploy/env-lib.sh` 会提前拦住并给出行号 |
|
||||
@@ -317,12 +329,12 @@ npm run dev # http://localhost:5173(/api 与 /health 代理到 3000)
|
||||
cd web-server
|
||||
npm run contracts:check # 契约版本一致性
|
||||
npm run typecheck # TypeScript 严格检查
|
||||
npm run test # 211 项单元测试 / 14 个文件(VMD 31、模型压缩包 27、
|
||||
npm run test # 220 项单元测试 / 15 个文件(VMD 31、模型压缩包 27、
|
||||
# 模型检查器 25、缩略图 8、骨骼过滤 8、
|
||||
# 预处理 25、init-env 16、admin-port 16、
|
||||
# access-log 9、VRM 检查器 6、.env 预检 12、
|
||||
# Assimp 定位与安装 13、stats 容量与编码 12、
|
||||
# 缩略图贴图采样 6)
|
||||
# 缩略图贴图采样 6、MMD 材质对齐 9)
|
||||
npm run build # 生产构建
|
||||
npm run start:prod & # 启动
|
||||
npm run test:smoke # 57 项端到端冒烟(需要数据库可连通)
|
||||
@@ -347,6 +359,7 @@ cd ../admin && npm run build # 管理端构建
|
||||
| `ASSIMP_BIN` | `assimp` | Assimp 可执行文件(`install.sh` 会自动安装并解析出绝对路径写入此项)。`.pmx/.fbx` 模型转换与 FBX/glTF 动作预处理需要;缺失时上传会失败并给出安装命令,只上传 `.glb/.vrm` 不受影响 |
|
||||
| `MODEL_CONVERT_FORMAT` | `glb` | 需要转换的模型(PMX/FBX)的交付格式:`glb`(两个客户端都原生加载)或 `vrm`。`vrm` = 在 GLB 之上补 `VRMC_vrm` 扩展(humanoid 骨骼 / 表情语义),humanoid 骨骼映射不全时自动回退交付 GLB 并写进 `conversion_note`。产物一律用 `assimp info` 回读校验 |
|
||||
| `MODEL_CONVERT_PMX` | `"Hatsune Miku.pmx"` | 压缩包内优先选用的 PMX 文件名(大小写不敏感);找不到时按「格式优先级 -> 目录最浅 -> 文件最大」挑选 |
|
||||
| `MODEL_SHADING` | `pbr` | 转换后模型的着色模式。`pbr`:标准 PBR,并按 PMX 参数修正 `doubleSided` / `metallic` / `roughness`;`unlit`:写 `KHR_materials_unlit`,颜色 = 贴图 x `baseColorFactor`、与场景光照无关,最接近 MMD 的平涂观感 |
|
||||
| `MODEL_CONVERT_TIMEOUT_MS` | `180000` | 单次转换超时(毫秒) |
|
||||
| `DEFAULT_MODEL_ID` | - | 可选:显式指定默认模型 id;不设置时按源码种子 `src/config/default-model.ts` 匹配,再回落到 VRM 优先规则 |
|
||||
| `CONTRACTS_DIR` | - | 可选:契约目录,设置后 `/health` 反映实时契约版本(原生部署默认指向 `/opt/opendance/contracts`) |
|
||||
|
||||
Reference in New Issue
Block a user