polywright-finish 是做什么的?
一个网格在通过目标检查、渲染中看起来正确、并以正确的尺寸和方向导入时才算完成。返回中心:../polywright/SKILL.md。引擎详情: references/engines.md。为某个引擎逐步制作和完成: references/roblox.md、references/unity.md、references/web-threejs.md。 弯曲、着色和纹理良好的网格:references/topology.md。
第一步:测量,然后决定
pw.py inspect <file> 和 pw.py check <file> --target <t> --real-size-m X。失败信息会告诉你该做什么:
三角面过多、没有 UV、材质过多、尺寸错误、开放边,以及对于游戏、Web 和 AR 目标,还包括翻转面或堆叠面以及不均匀的 UV 密度(inspect --topology;翻转面:convert --fix-winding)。
在每个破坏性步骤前后进行渲染(pw.py render)。
第二步:缩放、朝向、枢轴
- 以米为单位的实际尺寸:
pw.py convert in out --size-m X --ground --center(最长边设为 X;对于不规则形状使用已知维度)。一扇门是 2.0 到 2.1 米,椅子座面 0.45 米,桌子 0.75 米,人物 1.7 到 1.8 米。 - 道具的枢轴在底部中心,门在铰链处,轮子在轴心,武器在握柄处。
- 轴向:Blender Z 轴向上,正面朝 -Y;glTF Y 轴向上,正面朝 +Z;Unreal Z 轴向上,单位厘米;Unity Y 轴向上,左手坐标系;Roblox Y 轴向上,1 个 stud = 0.28 米。如有疑问,使用 1 米立方体和指向箭头测试导出。
第三步:针对目标的几何体
| 需求 | 操作 |
|---|---|
| 三角面更少,静态道具 | pw.py convert --max-tris N(折叠减面保持轮廓);LOD 使用 pw.py lods(每级约减半) |
| 三角面更少,会弯曲的网格 | 不进行减面:合并不弯曲处的环边,保留关节处的环边(references/topology.md) |
| 用于变形或雕刻的干净四边面 | 先体素重网格(闭合模型),然后用 QuadriFlow(配方在 polywright-blender)、Instant Meshes、Quad Remesher(付费)或托管式四边面重网格;角色需手动操作 |
| 生成的网格(密集、凹凸不平、软边) | 静态道具:减面并重新烘焙;英雄或动画角色:重拓扑并重新烘焙;或者使用更好的参考重新生成 |
| 多个部分应合并为一个 | --join;对于实体,使用 pw.py union |
| 碰撞 | 每个部件一个盒子、胶囊或凸包;Unreal 使用 UCX_ 前缀;Roblox 使用 CollisionFidelity Box 或 Hull;运动物体绝不能使用渲染网格 |
第四步:UV 和纹理
- UV:
pw.py convert --uv(智能 UV 投影)用于道具;第二套不重叠的 UV 集用于烘焙光照贴图(配方);套件内保持一致的纹素密度;使用装饰图集和纹理图集来减少材质和绘制调用。 - 从高模烘焙到低模:法线、环境光遮蔽、颜色(配方
bake-high-to-low)。重拓扑会破坏 UV,因此务必重新烘焙。 - PBR 金属粗糙度:金属度 0 或 1,粗糙度决定外观,漫反射颜色绝不能是纯黑或纯白;glTF 将环境光遮蔽、粗糙度、金属度分别打包到 R、G、B 通道(ORM)。
- 法线贴图:Blender、Unity、Godot、glTF、three.js、Roblox 使用 OpenGL(Y+);Unreal 使用 DirectX(Y-)。通过反转绿色通道来修复不匹配。纹理尺寸为 2 的幂;Web 和 AR 每个材质使用 1024 到 2048。
第五步:蒙皮(当它运动时)
A 姿势输入,干净流形网格。UniRig(MIT 协议,本地,8 GB)或托管式 Tripo、Meshy、AccuRIG(最干净的人形权重)、Mixamo(人形,最佳重定向文档)。2026 年的对比发现 Meshy 的髋部枢轴偏移 5 到 15 厘米(脚滑动),而 AccuRIG 以 0.01 的比例导入一次:蒙皮后检查缩放和枢轴。Roblox:每个顶点最多 4 个骨骼影响,根关节位于原点。Rigify 骨架导出的骨骼数量远多于其变形集(仅开启变形时有 706 个中的 278 个):为游戏构建仅变形骨架或使用上述方法。
动画片段:每个片段在少数共享的核心姿势上开始和结束,以便片段无需混合即可衔接;循环的第一帧等于最后一帧;为每个片段决定根运动或原地动画并记录;将附加片段(瞄准、注视、倾斜)作为基础姿势上的单独动作保留(Gregory,Game Engine Architecture 2e (2014),第 11.6 节)。
第六步:导出和验证
pw.py convert 写入 GLB、FBX、OBJ、USD/USDZ、STL。按目标:
| 目标 | 导出格式 | 然后 |
|---|---|---|
| game-roblox | 每个 MeshPart 使用 FBX、OBJ 或 GLB,低于 20k 三角面,一种材质 | 检查 --target game-roblox;robux 代理放置它 |
| game-unity | GLB(使用 glTFast)或 FBX --fbx-bake-axes | 在项目中进行导入测试(unity-agent) |
| game-unreal | FBX 或 GLB;对于密集不透明网格使用 Nanite | 导入时进行缩放检查 |
| web-threejs | GLB,然后 gltf-transform optimize in.glb out.glb --compress meshopt --texture-compress ktx2 --join-named false | gltf_validator;页面检查(threewright) |
| ar-usdz | convert in.glb out.usdz | 当安装 usd-core 时使用 usdchecker --arkit |
| video-blockout | 真实尺寸的 GLB 或 .blend,加上旋转台和深度/法线通道(配方) | 交给视频插件(cinewright) |
| commerce-gltf | GLB,真实尺寸,原点在底部中心,仅三角面 | check --target commerce-gltf |
按角度平滑是 Blender 4.1 及更高版本中的几何节点修改器:导出时应应用修改器,否则硬边会被平滑处理(glTF、FBX 和 OBJ 均如此,已在 5.2.1 上验证)。记录每次输出:pw.py manifest <dir> --add-output out/<file> --target <t> --inspect。
维护
常青单元,等级 moderate。配套文件:RESEARCH.md、CHANGELOG.md、
LEARNINGS.md、TESTS.md 包含 evals/evals.json、MAINTENANCE.md、
状态保存在 evergreen.json 中。每次使用时读取 evergreen.json;到期时刷新。